blob: e3dc17d778981b53162dedd5efc94a35e62fb04b [file] [log] [blame]
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05301#include <endian.h>
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10302#include <libpldm/base.h>
3#include <libpldm/firmware_update.h>
4#include <libpldm/pldm_types.h>
5#include <libpldm/utils.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05306
7#include <algorithm>
8#include <array>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <bitset>
Andrew Jeffery5a5129b2024-12-04 16:12:40 +103010#include <cstddef>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053011#include <cstdint>
Andrew Jeffery9c766792022-08-10 23:12:49 +093012#include <cstring>
Matt Johnstond5d1f662024-11-27 13:30:20 +080013#include <span>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053014#include <string>
15#include <string_view>
16#include <vector>
Andrew Jeffery9c766792022-08-10 23:12:49 +093017
Chris Wang4c1f2c72024-03-21 17:09:44 +080018#include "msgbuf.h"
19
Andrew Jefferydec237b2024-11-08 14:33:45 +103020#include <gmock/gmock.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093021#include <gtest/gtest.h>
22
Andrew Jefferydec237b2024-11-08 14:33:45 +103023using testing::ElementsAreArray;
24
Andrew Jeffery9c766792022-08-10 23:12:49 +093025constexpr auto hdrSize = sizeof(pldm_msg_hdr);
26
Matt Johnstoncf9a2df2024-11-07 15:29:29 +080027#ifdef LIBPLDM_API_TESTING
28
29static const uint8_t FIXED_INSTANCE_ID = 31;
30
31/* data is a pointer to pldm message response header */
32static void check_response(const void* data, uint8_t command)
33{
34 auto enc = static_cast<const pldm_msg*>(data);
35 EXPECT_EQ(enc->hdr.request, PLDM_RESPONSE);
36 EXPECT_EQ(enc->hdr.type, PLDM_FWUP);
37 EXPECT_EQ(enc->hdr.command, command);
38 EXPECT_EQ(enc->hdr.reserved, 0);
39 EXPECT_EQ(enc->hdr.datagram, 0);
40 EXPECT_EQ(enc->hdr.header_ver, 0);
41 EXPECT_EQ(enc->hdr.instance_id, FIXED_INSTANCE_ID);
42}
43#endif
44
Andrew Jefferye038b962025-03-06 16:04:59 +103045static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
46 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0{0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d,
47 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
48 0x05, 0x9a, 0xca, 0x02};
49
50static constexpr uint8_t PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0 = 0x01;
51
Andrew Jeffery9c766792022-08-10 23:12:49 +093052TEST(DecodePackageHeaderInfo, goodPath)
53{
Andrew Jeffery9c766792022-08-10 23:12:49 +093054 // Random PackageHeaderSize
55 constexpr uint16_t pkgHeaderSize = 303;
56 // PackageReleaseDateTime - "25/12/2021 00:00:00"
57 std::array<uint8_t, PLDM_TIMESTAMP104_SIZE> package_release_date_time{
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
60 constexpr uint16_t componentBitmapBitLength = 8;
61 // PackageVersionString
62 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +103063 constexpr size_t packageHeaderSize =
Andrew Jeffery9c766792022-08-10 23:12:49 +093064 sizeof(pldm_package_header_information) + packageVersionStr.size();
65
Andrew Jefferya3eba612025-03-06 17:11:20 +103066 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -060067 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
Andrew Jeffery9c766792022-08-10 23:12:49 +093068 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
70 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
71 pldm_package_header_information pkgHeader{};
72 variable_field packageVersion{};
73
74 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
75 packagerHeaderInfo.size(),
76 &pkgHeader, &packageVersion);
77
78 EXPECT_EQ(rc, PLDM_SUCCESS);
79 EXPECT_EQ(true,
80 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
Andrew Jefferye038b962025-03-06 16:04:59 +103081 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.begin(),
82 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.end()));
83 EXPECT_EQ(pkgHeader.package_header_format_version,
84 PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0);
Andrew Jeffery9c766792022-08-10 23:12:49 +093085 EXPECT_EQ(pkgHeader.package_header_size, pkgHeaderSize);
86 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
87 pkgHeader.package_release_date_time +
88 PLDM_TIMESTAMP104_SIZE,
89 package_release_date_time.begin(),
90 package_release_date_time.end()));
91 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
92 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
93 EXPECT_EQ(pkgHeader.package_version_string_length,
94 packageVersionStr.size());
95 std::string packageVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +093096 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +093097 reinterpret_cast<const char*>(packageVersion.ptr),
98 packageVersion.length);
99 EXPECT_EQ(packageVersionString, packageVersionStr);
100}
101
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030102TEST(DecodePackageHeaderInfo, invalidArguments)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930103{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930104 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +1030105 constexpr size_t packageHeaderSize =
Andrew Jeffery9c766792022-08-10 23:12:49 +0930106 sizeof(pldm_package_header_information) + packageVersionStr.size();
107
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030108 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
109 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
110 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
112 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
113
114 pldm_package_header_information packageHeader{};
115 variable_field packageVersion{};
116 int rc = 0;
117
118 rc = decode_pldm_package_header_info(nullptr, packagerHeaderInfo.size(),
119 &packageHeader, &packageVersion);
120 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
121
122 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
123 packagerHeaderInfo.size(), nullptr,
124 &packageVersion);
125 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
126
127 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
128 packagerHeaderInfo.size(),
129 &packageHeader, nullptr);
130 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
131}
132
133TEST(DecodePackageHeaderInfo, invalidPackageLengths)
134{
135 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
136 constexpr size_t packageHeaderSize =
137 sizeof(pldm_package_header_information) + packageVersionStr.size();
138
139 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
140 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
141 0x05, 0x9a, 0xca, 0x02, 0x01, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b,
143 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
144
145 pldm_package_header_information packageHeader{};
146 variable_field packageVersion{};
147 int rc = 0;
148
149 rc = decode_pldm_package_header_info(
150 packagerHeaderInfo.data(), sizeof(pldm_package_header_information) - 1,
151 &packageHeader, &packageVersion);
152 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
153}
154
155TEST(DecodePackageHeaderInfo, invalidPackageVersionStringType)
156{
157 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
158 constexpr size_t packageHeaderSize =
159 sizeof(pldm_package_header_information) + packageVersionStr.size();
160
161 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jefferya3eba612025-03-06 17:11:20 +1030162 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
163 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
164 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x06, 0x0b,
165 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930166
167 pldm_package_header_information packageHeader{};
168 variable_field packageVersion{};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030169 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930170
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030171 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
172 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930173 &packageHeader, &packageVersion);
174 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030175}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930176
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030177TEST(DecodePackageHeaderInfo, invalidPackageVersionStringLength)
178{
179 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
180 constexpr size_t packageHeaderSize =
181 sizeof(pldm_package_header_information) + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930182
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030183 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jefferya3eba612025-03-06 17:11:20 +1030184 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
185 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08, 0x00, 0x01, 0x00,
187 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030188
189 pldm_package_header_information packageHeader{};
190 variable_field packageVersion{};
191 int rc = 0;
192
193 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
194 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930195 &packageHeader, &packageVersion);
196 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030197}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930198
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030199TEST(DecodePackageHeaderInfo, corruptPackageVersionStringLength)
200{
201 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
202 constexpr size_t packageHeaderSize =
203 sizeof(pldm_package_header_information) + packageVersionStr.size();
204
Andrew Jefferya3eba612025-03-06 17:11:20 +1030205 constexpr std::array<uint8_t, packageHeaderSize - 1>
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030206 invalidPackagerHeaderInfo{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930207 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600208 0xa0, 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5,
210 0x07, 0x00, 0x08, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e,
211 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030212
213 pldm_package_header_information packageHeader{};
214 variable_field packageVersion{};
215 int rc = 0;
216
217 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
218 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930219 &packageHeader, &packageVersion);
220 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030221}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930222
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030223TEST(DecodePackageHeaderInfo, invalidComponentBitmapBitLength)
224{
225 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
226 constexpr size_t packageHeaderSize =
227 sizeof(pldm_package_header_information) + packageVersionStr.size();
228
229 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jefferya3eba612025-03-06 17:11:20 +1030230 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
231 0x05, 0x9a, 0xca, 0x02, 0x02, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x09, 0x00, 0x01, 0x0b,
233 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76, 0x31, 0x2e, 0x30};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030234
235 pldm_package_header_information packageHeader{};
236 variable_field packageVersion{};
237 int rc = 0;
238
239 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
240 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930241 &packageHeader, &packageVersion);
242 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
243}
244
245TEST(DecodeFirmwareDeviceIdRecord, goodPath)
246{
247 constexpr uint8_t descriptorCount = 1;
248 // Continue component updates after failure
249 constexpr std::bitset<32> deviceUpdateFlag{1};
250 constexpr uint16_t componentBitmapBitLength = 16;
251 // Applicable Components - 1,2,5,8,9
252 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
253 // ComponentImageSetVersionString
254 constexpr std::string_view imageSetVersionStr{"VersionString1"};
255 // Initial descriptor - UUID
256 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
257 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
258 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
259 constexpr uint16_t fwDevicePkgDataLen = 2;
260 // FirmwareDevicePackageData
261 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
262 0xcd};
263 // Size of the firmware device ID record
264 constexpr uint16_t recordLen =
265 sizeof(pldm_firmware_device_id_record) +
266 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
267 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
268 uuid.size() + fwDevicePkgData.size();
269 // Firmware device ID record
270 constexpr std::array<uint8_t, recordLen> record{
271 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
272 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
273 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
274 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
275 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
276
277 pldm_firmware_device_id_record deviceIdRecHeader{};
278 variable_field applicableComponents{};
279 variable_field outCompImageSetVersionStr{};
280 variable_field recordDescriptors{};
281 variable_field outFwDevicePkgData{};
282
283 auto rc = decode_firmware_device_id_record(
284 record.data(), record.size(), componentBitmapBitLength,
285 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
286 &recordDescriptors, &outFwDevicePkgData);
287
288 EXPECT_EQ(rc, PLDM_SUCCESS);
289 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
290 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
291 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
292 deviceUpdateFlag);
293 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
294 PLDM_STR_TYPE_ASCII);
295 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
296 imageSetVersionStr.size());
297 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
298
299 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
300 EXPECT_EQ(true,
301 std::equal(applicableComponents.ptr,
302 applicableComponents.ptr + applicableComponents.length,
303 applicableComponentsBitfield.begin(),
304 applicableComponentsBitfield.end()));
305
306 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
307 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930308 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930309 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
310 outCompImageSetVersionStr.length);
311 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
312
313 uint16_t descriptorType = 0;
314 uint16_t descriptorLen = 0;
315 variable_field descriptorData{};
316 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
317 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
318 recordDescriptors.length,
319 &descriptorType, &descriptorData);
320 EXPECT_EQ(rc, PLDM_SUCCESS);
321 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
322 sizeof(descriptorLen) +
323 descriptorData.length);
324 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
325 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
326 EXPECT_EQ(true, std::equal(descriptorData.ptr,
327 descriptorData.ptr + descriptorData.length,
328 uuid.begin(), uuid.end()));
329
330 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
331 EXPECT_EQ(true,
332 std::equal(outFwDevicePkgData.ptr,
333 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
334 fwDevicePkgData.begin(), fwDevicePkgData.end()));
335}
336
337TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
338{
339 constexpr uint8_t descriptorCount = 1;
340 // Continue component updates after failure
341 constexpr std::bitset<32> deviceUpdateFlag{1};
342 constexpr uint16_t componentBitmapBitLength = 8;
343 // Applicable Components - 1,2
344 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
345 // ComponentImageSetVersionString
346 constexpr std::string_view imageSetVersionStr{"VersionString1"};
347 // Initial descriptor - UUID
348 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
349 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
350 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
351 constexpr uint16_t fwDevicePkgDataLen = 0;
352
353 // Size of the firmware device ID record
354 constexpr uint16_t recordLen =
355 sizeof(pldm_firmware_device_id_record) +
356 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
357 imageSetVersionStr.size() +
358 sizeof(pldm_descriptor_tlv().descriptor_type) +
359 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
360 fwDevicePkgDataLen;
361 // Firmware device ID record
362 constexpr std::array<uint8_t, recordLen> record{
363 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
364 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
365 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
366 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
367
368 pldm_firmware_device_id_record deviceIdRecHeader{};
369 variable_field applicableComponents{};
370 variable_field outCompImageSetVersionStr{};
371 variable_field recordDescriptors{};
372 variable_field outFwDevicePkgData{};
373
374 auto rc = decode_firmware_device_id_record(
375 record.data(), record.size(), componentBitmapBitLength,
376 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
377 &recordDescriptors, &outFwDevicePkgData);
378
379 EXPECT_EQ(rc, PLDM_SUCCESS);
380 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
381 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
382 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
383 deviceUpdateFlag);
384 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
385 PLDM_STR_TYPE_ASCII);
386 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
387 imageSetVersionStr.size());
388 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
389
390 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
391 EXPECT_EQ(true,
392 std::equal(applicableComponents.ptr,
393 applicableComponents.ptr + applicableComponents.length,
394 applicableComponentsBitfield.begin(),
395 applicableComponentsBitfield.end()));
396
397 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
398 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930399 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930400 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
401 outCompImageSetVersionStr.length);
402 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
403
404 uint16_t descriptorType = 0;
405 uint16_t descriptorLen = 0;
406 variable_field descriptorData{};
407 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
408 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
409 recordDescriptors.length,
410 &descriptorType, &descriptorData);
411 EXPECT_EQ(rc, PLDM_SUCCESS);
412 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
413 sizeof(descriptorLen) +
414 descriptorData.length);
415 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
416 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
417 EXPECT_EQ(true, std::equal(descriptorData.ptr,
418 descriptorData.ptr + descriptorData.length,
419 uuid.begin(), uuid.end()));
420
421 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
422 EXPECT_EQ(outFwDevicePkgData.length, 0);
423}
424
425TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
426{
427 constexpr uint16_t componentBitmapBitLength = 8;
428 // Invalid ComponentImageSetVersionStringType
429 constexpr std::array<uint8_t, 11> invalidRecord1{
430 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
431
432 int rc = 0;
433 pldm_firmware_device_id_record deviceIdRecHeader{};
434 variable_field applicableComponents{};
435 variable_field outCompImageSetVersionStr{};
436 variable_field recordDescriptors{};
437 variable_field outFwDevicePkgData{};
438
439 rc = decode_firmware_device_id_record(
440 nullptr, invalidRecord1.size(), componentBitmapBitLength,
441 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
442 &recordDescriptors, &outFwDevicePkgData);
443 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
444
445 rc = decode_firmware_device_id_record(
446 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
447 nullptr, &applicableComponents, &outCompImageSetVersionStr,
448 &recordDescriptors, &outFwDevicePkgData);
449 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
450
451 rc = decode_firmware_device_id_record(
452 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
453 &deviceIdRecHeader, nullptr, &outCompImageSetVersionStr,
454 &recordDescriptors, &outFwDevicePkgData);
455 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
456
457 rc = decode_firmware_device_id_record(
458 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
459 &deviceIdRecHeader, &applicableComponents, nullptr, &recordDescriptors,
460 &outFwDevicePkgData);
461 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
462
463 rc = decode_firmware_device_id_record(
464 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
465 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
466 nullptr, &outFwDevicePkgData);
467 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
468
469 rc = decode_firmware_device_id_record(
470 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
471 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
472 &recordDescriptors, nullptr);
473 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
474
475 rc = decode_firmware_device_id_record(
476 invalidRecord1.data(), invalidRecord1.size() - 1,
477 componentBitmapBitLength, &deviceIdRecHeader, &applicableComponents,
478 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
479 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
480
481 rc = decode_firmware_device_id_record(
482 invalidRecord1.data(), invalidRecord1.size(),
483 componentBitmapBitLength + 1, &deviceIdRecHeader, &applicableComponents,
484 &outCompImageSetVersionStr, &recordDescriptors, &outFwDevicePkgData);
485 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
486
487 rc = decode_firmware_device_id_record(
488 invalidRecord1.data(), invalidRecord1.size(), componentBitmapBitLength,
489 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
490 &recordDescriptors, &outFwDevicePkgData);
491 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
492
493 // Invalid ComponentImageSetVersionStringLength
494 constexpr std::array<uint8_t, 11> invalidRecord2{
495 0x0b, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
496 rc = decode_firmware_device_id_record(
497 invalidRecord2.data(), invalidRecord2.size(), componentBitmapBitLength,
498 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
499 &recordDescriptors, &outFwDevicePkgData);
500 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
501
502 // invalidRecord3 size is less than RecordLength
503 constexpr std::array<uint8_t, 11> invalidRecord3{
504 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00};
505 rc = decode_firmware_device_id_record(
506 invalidRecord3.data(), invalidRecord3.size(), componentBitmapBitLength,
507 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
508 &recordDescriptors, &outFwDevicePkgData);
509 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
510
511 // RecordLength is less than the calculated RecordLength
512 constexpr std::array<uint8_t, 11> invalidRecord4{
513 0x15, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02, 0x00};
514 rc = decode_firmware_device_id_record(
515 invalidRecord4.data(), invalidRecord4.size(), componentBitmapBitLength,
516 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
517 &recordDescriptors, &outFwDevicePkgData);
518 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800519
520 // Large FirmwareDevicePackageDataLength could cause overflow in calculation
521 constexpr std::array<uint8_t, 49> invalidRecord5{
522 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
523 // FirmwareDevicePackageDataLength = 0xffff
524 0xff, 0xff,
525 //
526 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
527 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
528 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
529 0xab, 0xcd};
530 rc = decode_firmware_device_id_record(
531 invalidRecord5.data(), invalidRecord5.size(), componentBitmapBitLength,
532 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
533 &recordDescriptors, &outFwDevicePkgData);
534 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930535}
536
537TEST(DecodeDescriptors, goodPath3Descriptors)
538{
539 // In the descriptor data there are 3 descriptor entries
540 // 1) IANA enterprise ID
541 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
542 0x0a, 0x0b, 0x0c, 0xd};
543 // 2) UUID
544 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
545 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
546 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
547 // 3) Vendor Defined
548 constexpr std::string_view vendorTitle{"OpenBMC"};
549 constexpr size_t vendorDescriptorLen = 2;
550 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
551 0x01, 0x02};
552
553 constexpr size_t vendorDefinedDescriptorLen =
554 sizeof(pldm_vendor_defined_descriptor_title_data()
555 .vendor_defined_descriptor_title_str_type) +
556 sizeof(pldm_vendor_defined_descriptor_title_data()
557 .vendor_defined_descriptor_title_str_len) +
558 vendorTitle.size() + vendorDescriptorData.size();
559
560 constexpr size_t descriptorsLength =
561 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
562 sizeof(pldm_descriptor_tlv().descriptor_length)) +
563 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
564
565 constexpr std::array<uint8_t, descriptorsLength> descriptors{
566 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
567 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600568 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930569 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
570
571 size_t descriptorCount = 1;
572 size_t descriptorsRemainingLength = descriptorsLength;
573 int rc = 0;
574
575 while (descriptorsRemainingLength && (descriptorCount <= 3))
576 {
577 uint16_t descriptorType = 0;
578 uint16_t descriptorLen = 0;
579 variable_field descriptorData{};
580
581 rc = decode_descriptor_type_length_value(
582 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
583 descriptorsRemainingLength, &descriptorType, &descriptorData);
584 EXPECT_EQ(rc, PLDM_SUCCESS);
585
586 if (descriptorCount == 1)
587 {
588 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
589 EXPECT_EQ(descriptorData.length,
590 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
591 EXPECT_EQ(true,
592 std::equal(descriptorData.ptr,
593 descriptorData.ptr + descriptorData.length,
594 iana.begin(), iana.end()));
595 }
596 else if (descriptorCount == 2)
597 {
598 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
599 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
600 EXPECT_EQ(true,
601 std::equal(descriptorData.ptr,
602 descriptorData.ptr + descriptorData.length,
603 uuid.begin(), uuid.end()));
604 }
605 else if (descriptorCount == 3)
606 {
607 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
608 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
609
610 uint8_t descriptorTitleStrType = 0;
611 variable_field descriptorTitleStr{};
612 variable_field vendorDefinedDescriptorData{};
613
614 rc = decode_vendor_defined_descriptor_value(
615 descriptorData.ptr, descriptorData.length,
616 &descriptorTitleStrType, &descriptorTitleStr,
617 &vendorDefinedDescriptorData);
618 EXPECT_EQ(rc, PLDM_SUCCESS);
619
620 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
621 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
622 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930623 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930624 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
625 descriptorTitleStr.length);
626 EXPECT_EQ(vendorTitleStr, vendorTitle);
627
628 EXPECT_EQ(vendorDefinedDescriptorData.length,
629 vendorDescriptorData.size());
630 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
631 vendorDefinedDescriptorData.ptr +
632 vendorDefinedDescriptorData.length,
633 vendorDescriptorData.begin(),
634 vendorDescriptorData.end()));
635 }
636
637 descriptorsRemainingLength -= sizeof(descriptorType) +
638 sizeof(descriptorLen) +
639 descriptorData.length;
640 descriptorCount++;
641 }
642}
643
644TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
645{
646 int rc = 0;
647 // IANA Enterprise ID descriptor length incorrect
648 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
649 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
650 uint16_t descriptorType = 0;
651 variable_field descriptorData{};
652
653 rc = decode_descriptor_type_length_value(nullptr,
654 invalidIANADescriptor1.size(),
655 &descriptorType, &descriptorData);
656 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
657
658 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
659 invalidIANADescriptor1.size(),
660 nullptr, &descriptorData);
661 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
662
663 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
664 invalidIANADescriptor1.size(),
665 &descriptorType, nullptr);
666 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
667
668 rc = decode_descriptor_type_length_value(
669 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
670 &descriptorType, &descriptorData);
671 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
672
673 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
674 invalidIANADescriptor1.size(),
675 &descriptorType, &descriptorData);
Andrew Jeffery779e9db2025-02-21 12:14:28 +1030676 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930677
678 // IANA Enterprise ID descriptor data less than length
679 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
680 0x0a, 0x0b, 0x0c};
681 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
682 invalidIANADescriptor2.size(),
683 &descriptorType, &descriptorData);
684 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
685}
686
687TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
688{
689 int rc = 0;
690 // VendorDefinedDescriptorTitleStringType is invalid
691 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
692 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
693 uint8_t descriptorStringType = 0;
694 variable_field descriptorTitleStr{};
695 variable_field vendorDefinedDescriptorData{};
696
697 rc = decode_vendor_defined_descriptor_value(
698 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
699 &descriptorTitleStr, &vendorDefinedDescriptorData);
700 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
701
702 rc = decode_vendor_defined_descriptor_value(
703 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
704 &descriptorStringType, &descriptorTitleStr,
705 &vendorDefinedDescriptorData);
706 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
707
708 rc = decode_vendor_defined_descriptor_value(
709 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
710 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
711 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
712
713 rc = decode_vendor_defined_descriptor_value(
714 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
715 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
716 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
717
718 rc = decode_vendor_defined_descriptor_value(
719 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
720 &descriptorStringType, &descriptorTitleStr, nullptr);
721 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
722
723 rc = decode_vendor_defined_descriptor_value(
724 invalidVendorDescriptor1.data(),
725 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
726 &descriptorStringType, &descriptorTitleStr,
727 &vendorDefinedDescriptorData);
728 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
729
730 rc = decode_vendor_defined_descriptor_value(
731 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
732 &descriptorStringType, &descriptorTitleStr,
733 &vendorDefinedDescriptorData);
734 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
735
736 // VendorDefinedDescriptorTitleStringLength is 0
737 std::array<uint8_t, 9> invalidVendorDescriptor2{
738 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
739 rc = decode_vendor_defined_descriptor_value(
740 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
741 &descriptorStringType, &descriptorTitleStr,
742 &vendorDefinedDescriptorData);
743 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
744
745 // VendorDefinedDescriptorData not present in the data
746 std::array<uint8_t, 9> invalidVendorDescriptor3{
747 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
748 rc = decode_vendor_defined_descriptor_value(
749 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
750 &descriptorStringType, &descriptorTitleStr,
751 &vendorDefinedDescriptorData);
752 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
753}
754
755TEST(DecodeComponentImageInfo, goodPath)
756{
757 // Firmware
758 constexpr uint16_t compClassification = 16;
759 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600760 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930761 // Force update
762 constexpr std::bitset<16> compOptions{1};
763 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
764 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
765 // Random ComponentLocationOffset
766 constexpr uint32_t compLocOffset = 357;
767 // Random ComponentSize
768 constexpr uint32_t compSize = 27;
769 // ComponentVersionString
770 constexpr std::string_view compVersionStr{"VersionString1"};
771 constexpr size_t compImageInfoSize =
772 sizeof(pldm_component_image_information) + compVersionStr.size();
773
774 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
775 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
776 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
777 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
778 pldm_component_image_information outCompImageInfo{};
779 variable_field outCompVersionStr{};
780
781 auto rc =
782 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
783 &outCompImageInfo, &outCompVersionStr);
784
785 EXPECT_EQ(rc, PLDM_SUCCESS);
786 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
787 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
788 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
789 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
790 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
791 reqCompActivationMethod);
792 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
793 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
794 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
795 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
796 compVersionStr.size());
797
798 EXPECT_EQ(outCompVersionStr.length,
799 outCompImageInfo.comp_version_string_length);
800 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930801 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930802 reinterpret_cast<const char*>(outCompVersionStr.ptr),
803 outCompVersionStr.length);
804 EXPECT_EQ(componentVersionString, compVersionStr);
805}
806
807TEST(DecodeComponentImageInfo, errorPaths)
808{
809 int rc = 0;
810 // ComponentVersionString
811 constexpr std::string_view compVersionStr{"VersionString1"};
812 constexpr size_t compImageInfoSize =
813 sizeof(pldm_component_image_information) + compVersionStr.size();
814 // Invalid ComponentVersionStringType - 0x06
815 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
816 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
817 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
818 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
819 pldm_component_image_information outCompImageInfo{};
820 variable_field outCompVersionStr{};
821
822 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
823 &outCompImageInfo, &outCompVersionStr);
824 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
825
826 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
827 invalidCompImageInfo1.size(), nullptr,
828 &outCompVersionStr);
829 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
830
831 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
832 invalidCompImageInfo1.size(),
833 &outCompImageInfo, nullptr);
834 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
835
836 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
837 sizeof(pldm_component_image_information) -
838 1,
839 &outCompImageInfo, &outCompVersionStr);
840 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
841
842 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
843 invalidCompImageInfo1.size(),
844 &outCompImageInfo, &outCompVersionStr);
845 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
846
847 // Invalid ComponentVersionStringLength - 0x00
848 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
849 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
850 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
851 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
852 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
853 invalidCompImageInfo2.size(),
854 &outCompImageInfo, &outCompVersionStr);
855 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
856
857 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600858 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +0930859 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
860 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
861 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
862 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
863
864 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
865 invalidCompImageInfo3.size() - 1,
866 &outCompImageInfo, &outCompVersionStr);
867 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
868
869 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
870 invalidCompImageInfo3.size(),
871 &outCompImageInfo, &outCompVersionStr);
872 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
873
874 // Invalid ComponentLocationOffset - 0
875 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
876 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
877 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
878 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
879 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
880 invalidCompImageInfo4.size(),
881 &outCompImageInfo, &outCompVersionStr);
882 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
883
884 // Invalid ComponentSize - 0
885 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
886 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
887 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
888 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
889 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
890 invalidCompImageInfo5.size(),
891 &outCompImageInfo, &outCompVersionStr);
892 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
893}
894
895TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
896{
897 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930898 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930899 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
900
901 uint8_t instanceId = 0x01;
902
903 auto rc = encode_query_device_identifiers_req(
904 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
905 EXPECT_EQ(rc, PLDM_SUCCESS);
906 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
907 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
908 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
909 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
910}
911
912TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
913{
914 // descriptorDataLen is not fixed here taking it as 6
915 constexpr uint8_t descriptorDataLen = 6;
916 std::array<uint8_t, hdrSize +
917 sizeof(struct pldm_query_device_identifiers_resp) +
918 descriptorDataLen>
919 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930920 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930921 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
922 responseMsg.data() + hdrSize);
923
924 inResp->completion_code = PLDM_SUCCESS;
925 inResp->device_identifiers_len = htole32(descriptorDataLen);
926 inResp->descriptor_count = 1;
927
928 // filling descriptor data
929 std::fill_n(responseMsg.data() + hdrSize +
930 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600931 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930932
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930933 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930934 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
935 uint8_t completionCode = PLDM_SUCCESS;
936 uint32_t deviceIdentifiersLen = 0;
937 uint8_t descriptorCount = 0;
938 uint8_t* outDescriptorData = nullptr;
939
940 auto rc = decode_query_device_identifiers_resp(
941 response, responseMsg.size() - hdrSize, &completionCode,
942 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
943
944 EXPECT_EQ(rc, PLDM_SUCCESS);
945 EXPECT_EQ(completionCode, PLDM_SUCCESS);
946 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
947 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
948 EXPECT_EQ(true,
949 std::equal(outDescriptorData,
950 outDescriptorData + deviceIdentifiersLen,
951 responseMsg.begin() + hdrSize +
952 sizeof(struct pldm_query_device_identifiers_resp),
953 responseMsg.end()));
954}
955
Matt Johnstoncf9a2df2024-11-07 15:29:29 +0800956#ifdef LIBPLDM_API_TESTING
957TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
958{
959 int rc;
960 PLDM_MSG_DEFINE_P(enc, 1000);
961 size_t enc_payload_len = 1000;
962 pldm_descriptor check_desc[] = {
963 {
964 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
965 .descriptor_length = 4,
966 .descriptor_data = "a123",
967 },
968 {
969 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
970 .descriptor_length = 3,
971 .descriptor_data = "987",
972 },
973 };
974 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
975 enc, &enc_payload_len);
976 EXPECT_EQ(rc, 0);
977 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
978 ElementsAreArray<uint8_t>({
979 // completion code
980 0x00,
981 // device identifiers length = 15
982 0x0f,
983 0x00,
984 0x00,
985 0x00,
986 // descriptor count
987 0x02,
988 // desc 0
989 0x01,
990 0x00,
991 0x04,
992 0x00,
993 0x61,
994 0x31,
995 0x32,
996 0x33,
997 // desc 1
998 0xff,
999 0xff,
1000 0x03,
1001 0x00,
1002 0x39,
1003 0x38,
1004 0x37,
1005 }));
1006
1007 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
1008}
1009#endif
1010
Andrew Jeffery9c766792022-08-10 23:12:49 +09301011TEST(GetFirmwareParameters, goodPathEncodeRequest)
1012{
1013 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301014 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301015 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1016 uint8_t instanceId = 0x01;
1017
1018 auto rc = encode_get_firmware_parameters_req(
1019 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
1020 EXPECT_EQ(rc, PLDM_SUCCESS);
1021 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1022 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1023 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1024 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
1025}
1026
1027TEST(GetFirmwareParameters, decodeResponse)
1028{
1029 // CapabilitiesDuringUpdate of the firmware device
1030 // Firmware device downgrade restrictions [Bit position 8] &
1031 // Firmware Device Partial Updates [Bit position 3]
1032 constexpr std::bitset<32> fdCapabilities{0x00000104};
1033 constexpr uint16_t compCount = 1;
1034 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1035 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1036
1037 // constexpr uint16_t compClassification = 16;
1038 // constexpr uint16_t compIdentifier = 300;
1039 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001040 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301041 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
1042 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1043 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
1044 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
1045 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
1046 constexpr std::string_view activeCompVersion{"VersionString3"};
1047 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +09301048
1049 constexpr size_t compParamTableSize =
1050 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
1051 pendingCompVersion.size();
1052
1053 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001054 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301055 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1056 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
1057 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
1058 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1059 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1060
1061 constexpr size_t getFwParamsPayloadLen =
1062 sizeof(pldm_get_firmware_parameters_resp) +
1063 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1064 compParamTableSize;
1065
1066 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1067 getFwParamsResponse{
1068 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 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, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001072 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301073 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1074 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1075 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1076 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1077 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1078
1079 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301080 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301081 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1082 pldm_get_firmware_parameters_resp outResp{};
1083 variable_field outActiveCompImageSetVersion{};
1084 variable_field outPendingCompImageSetVersion{};
1085 variable_field outCompParameterTable{};
1086
1087 auto rc = decode_get_firmware_parameters_resp(
1088 responseMsg, getFwParamsPayloadLen, &outResp,
1089 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1090 &outCompParameterTable);
1091
1092 EXPECT_EQ(rc, PLDM_SUCCESS);
1093 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1094 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1095 EXPECT_EQ(outResp.comp_count, compCount);
1096 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1097 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1098 activeCompImageSetVersion.size());
1099 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1100 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1101 pendingCompImageSetVersion.size());
1102 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301103 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301104 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1105 outActiveCompImageSetVersion.length);
1106 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1107 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301108 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301109 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1110 outPendingCompImageSetVersion.length);
1111 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1112 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1113 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1114 outCompParameterTable.ptr +
1115 outCompParameterTable.length,
1116 compParamTable.begin(), compParamTable.end()));
1117}
1118
1119TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1120{
1121 // CapabilitiesDuringUpdate of the firmware device
1122 // FD Host Functionality during Firmware Update [Bit position 2] &
1123 // Component Update Failure Retry Capability [Bit position 1]
1124 constexpr std::bitset<32> fdCapabilities{0x06};
1125 constexpr uint16_t compCount = 0;
1126 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1127 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1128
1129 constexpr size_t getFwParamsPayloadLen =
1130 sizeof(pldm_get_firmware_parameters_resp) +
1131 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1132
1133 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1134 getFwParamsResponse{
1135 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1136 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1137 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1138 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1139
1140 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301141 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301142 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1143 pldm_get_firmware_parameters_resp outResp{};
1144 variable_field outActiveCompImageSetVersion{};
1145 variable_field outPendingCompImageSetVersion{};
1146 variable_field outCompParameterTable{};
1147
1148 auto rc = decode_get_firmware_parameters_resp(
1149 responseMsg, getFwParamsPayloadLen, &outResp,
1150 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1151 &outCompParameterTable);
1152
1153 EXPECT_EQ(rc, PLDM_SUCCESS);
1154 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1155 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1156 EXPECT_EQ(outResp.comp_count, compCount);
1157 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1158 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1159 activeCompImageSetVersion.size());
1160 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1161 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1162 pendingCompImageSetVersion.size());
1163 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301164 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301165 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1166 outActiveCompImageSetVersion.length);
1167 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1168 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301169 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301170 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1171 outPendingCompImageSetVersion.length);
1172 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1173 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1174 EXPECT_EQ(outCompParameterTable.length, 0);
1175}
1176
1177TEST(GetFirmwareParameters,
1178 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1179{
1180 // CapabilitiesDuringUpdate of the firmware device
1181 // FD Host Functionality during Firmware Update [Bit position 2] &
1182 // Component Update Failure Retry Capability [Bit position 1]
1183 constexpr std::bitset<32> fdCapabilities{0x06};
1184 constexpr uint16_t compCount = 0;
1185 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1186
1187 constexpr size_t getFwParamsPayloadLen =
1188 sizeof(pldm_get_firmware_parameters_resp) +
1189 activeCompImageSetVersion.size();
1190
1191 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1192 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1193 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1194 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1195 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1196
1197 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301198 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301199 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1200 pldm_get_firmware_parameters_resp outResp{};
1201 variable_field outActiveCompImageSetVersion{};
1202 variable_field outPendingCompImageSetVersion{};
1203 variable_field outCompParameterTable{};
1204
1205 auto rc = decode_get_firmware_parameters_resp(
1206 responseMsg, getFwParamsPayloadLen, &outResp,
1207 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1208 &outCompParameterTable);
1209
1210 EXPECT_EQ(rc, PLDM_SUCCESS);
1211 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1212 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1213 EXPECT_EQ(outResp.comp_count, compCount);
1214 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1215 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1216 activeCompImageSetVersion.size());
1217 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1218 PLDM_STR_TYPE_UNKNOWN);
1219 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1220 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301221 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301222 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1223 outActiveCompImageSetVersion.length);
1224 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1225 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1226 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1227 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1228 EXPECT_EQ(outCompParameterTable.length, 0);
1229}
1230
1231TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1232{
1233 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1234 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1235
1236 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301237 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301238 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1239 pldm_get_firmware_parameters_resp outResp{};
1240 variable_field outActiveCompImageSetVersion{};
1241 variable_field outPendingCompImageSetVersion{};
1242 variable_field outCompParameterTable{};
1243
1244 auto rc = decode_get_firmware_parameters_resp(
1245 responseMsg, getFwParamsResponse.size(), &outResp,
1246 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1247 &outCompParameterTable);
1248
1249 EXPECT_EQ(rc, PLDM_SUCCESS);
1250 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1251}
1252
1253TEST(GetFirmwareParameters, errorPathdecodeResponse)
1254{
1255 int rc = 0;
1256 // Invalid ActiveComponentImageSetVersionStringType
1257 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1259 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1260
1261 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301262 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301263 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1264 pldm_get_firmware_parameters_resp outResp{};
1265 variable_field outActiveCompImageSetVersion{};
1266 variable_field outPendingCompImageSetVersion{};
1267 variable_field outCompParameterTable{};
1268
1269 rc = decode_get_firmware_parameters_resp(
1270 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1271 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1272 &outCompParameterTable);
1273 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1274
1275 rc = decode_get_firmware_parameters_resp(
1276 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1277 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1278 &outCompParameterTable);
1279 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1280
1281 rc = decode_get_firmware_parameters_resp(
1282 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1283 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1284 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1285
1286 rc = decode_get_firmware_parameters_resp(
1287 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1288 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1289 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1290
1291 rc = decode_get_firmware_parameters_resp(
1292 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1293 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1294 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1295
1296 rc = decode_get_firmware_parameters_resp(
1297 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1298 &outPendingCompImageSetVersion, &outCompParameterTable);
1299 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1300
1301 rc = decode_get_firmware_parameters_resp(
1302 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1303 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1304 &outCompParameterTable);
1305 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1306
1307 rc = decode_get_firmware_parameters_resp(
1308 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1309 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1310 &outCompParameterTable);
1311 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1312
1313 // Invalid ActiveComponentImageSetVersionStringLength
1314 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1316 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1317 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301318 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301319 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1320 rc = decode_get_firmware_parameters_resp(
1321 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1322 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1323 &outCompParameterTable);
1324 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1325
1326 // Invalid PendingComponentImageSetVersionStringType &
1327 // PendingComponentImageSetVersionStringLength
1328 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1329 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1330 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1331 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301332 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301333 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1334 rc = decode_get_firmware_parameters_resp(
1335 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1336 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1337 &outCompParameterTable);
1338 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1339
1340 // Invalid PendingComponentImageSetVersionStringType &
1341 // PendingComponentImageSetVersionStringLength
1342 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1343 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1344 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1345 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301346 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301347 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1348 rc = decode_get_firmware_parameters_resp(
1349 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1350 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1351 &outCompParameterTable);
1352 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1353
1354 // Total payload length less than expected
1355 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1356 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1357 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1358 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301359 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301360 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1361 rc = decode_get_firmware_parameters_resp(
1362 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1363 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1364 &outCompParameterTable);
1365 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1366}
1367
1368TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1369{
1370 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001371 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301372 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001373 constexpr uint16_t compIdentifier = 0x0c0d;
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001374 constexpr uint16_t compClassificationIndex = 0xf;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301375 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001376 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301377 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001378 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301379 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001380 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301381
1382 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1383 constexpr uint8_t activeCompVerStrLen = 8;
1384 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1385 constexpr uint8_t pendingCompVerStrLen = 8;
1386 constexpr size_t entryLength =
1387 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1388 pendingCompVerStrLen;
1389 std::array<uint8_t, entryLength> entry{};
1390
1391 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301392 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301393 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1394
1395 inEntry->comp_classification = htole16(compClassification);
1396 inEntry->comp_identifier = htole16(compIdentifier);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001397 inEntry->comp_classification_index = compClassificationIndex;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301398 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1399 inEntry->active_comp_ver_str_type = 1;
1400 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1401 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001402 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301403 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1404 inEntry->pending_comp_ver_str_type = 1;
1405 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1406 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001407 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301408 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1409 inEntry->capabilities_during_update.value =
1410 htole32(capabilitiesDuringUpdate);
1411 constexpr auto activeCompVerStrPos =
1412 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001413 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301414 constexpr auto pendingCompVerStrPos =
1415 activeCompVerStrPos + activeCompVerStrLen;
1416 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001417 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301418
1419 struct pldm_component_parameter_entry outEntry;
1420 struct variable_field outActiveCompVerStr;
1421 struct variable_field outPendingCompVerStr;
1422
1423 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1424 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1425 &outPendingCompVerStr);
1426
1427 EXPECT_EQ(rc, PLDM_SUCCESS);
1428
1429 EXPECT_EQ(outEntry.comp_classification, compClassification);
1430 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1431 EXPECT_EQ(inEntry->comp_classification_index,
1432 outEntry.comp_classification_index);
1433 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1434 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1435 outEntry.active_comp_ver_str_type);
1436 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1437 outEntry.active_comp_ver_str_len);
1438 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1439 outEntry.active_comp_release_date,
1440 sizeof(inEntry->active_comp_release_date)));
1441 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1442 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1443 outEntry.pending_comp_ver_str_type);
1444 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1445 outEntry.pending_comp_ver_str_len);
1446 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1447 outEntry.pending_comp_release_date,
1448 sizeof(inEntry->pending_comp_release_date)));
1449 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1450 EXPECT_EQ(outEntry.capabilities_during_update.value,
1451 capabilitiesDuringUpdate);
1452
1453 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1454 entry.data() + activeCompVerStrPos,
1455 outActiveCompVerStr.length));
1456 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1457 entry.data() + pendingCompVerStrPos,
1458 outPendingCompVerStr.length));
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001459
1460#ifdef LIBPLDM_API_TESTING
1461 /* Check the roundtrip matches */
1462 std::vector<uint8_t> enc_data(1000);
1463 size_t enc_payload_len = enc_data.size();
1464 struct pldm_component_parameter_entry_full entryFull = {
1465 .comp_classification = compClassification,
1466 .comp_identifier = compIdentifier,
1467 .comp_classification_index = compClassificationIndex,
1468 .active_ver =
1469 {
1470 .comparison_stamp = 0x12345678,
1471 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1472 .str_len = activeCompVerStrLen,
1473 .str_data = {}},
1474 .date = {},
1475 },
1476 .pending_ver =
1477 {
1478 .comparison_stamp = 0x12345678,
1479 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1480 .str_len = pendingCompVerStrLen,
1481 .str_data = {}},
1482 .date = {},
1483 },
1484 .comp_activation_methods = inEntry->comp_activation_methods,
1485 .capabilities_during_update = inEntry->capabilities_during_update,
1486 };
1487 // Fill strings
1488 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1489 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1490 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1491 0xff);
1492 std::fill_n(entryFull.pending_ver.date,
1493 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1494
1495 rc = encode_get_firmware_parameters_resp_comp_entry(
1496 &entryFull, enc_data.data(), &enc_payload_len);
1497 EXPECT_EQ(rc, PLDM_SUCCESS);
1498 EXPECT_EQ(enc_payload_len, entryLength);
1499 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1500#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301501}
1502
Chris Wang4c1f2c72024-03-21 17:09:44 +08001503TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1504{
1505 constexpr uint8_t instanceId = 1;
1506 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301507 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001508 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1509
1510 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1511
Unive Tien71e935c2024-11-25 17:21:43 +08001512 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001513 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1514 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1515 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1516 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1517}
1518
1519TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1520{
1521 constexpr uint8_t instanceId = 1;
1522
1523 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1524
Unive Tien71e935c2024-11-25 17:21:43 +08001525 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001526}
1527
1528TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1529{
1530 uint8_t completion_code_resp = PLDM_SUCCESS;
1531 uint8_t downstream_device_update_supported_resp =
1532 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1533 uint16_t number_of_downstream_devices_resp = 1;
1534 uint16_t max_number_of_downstream_devices_resp = 1;
1535 /** Capabilities of updating downstream devices
1536 * FDP supports downstream devices dynamically attached [Bit position 0] &
1537 * FDP supports downstream devices dynamically removed [Bit position 1]
1538 */
1539 bitfield32_t capabilities_resp = {.value = 0x0002};
1540 int rc;
1541
1542 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1543 responseMsg{};
1544
Andrew Jefferya1896962025-03-03 21:41:25 +10301545 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301546 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1547 responseMsg.size() - hdrSize);
1548 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001549
1550 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1551 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1552 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1553 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1554 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301555 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001556
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301557 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001558 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1559 struct pldm_query_downstream_devices_resp resp_data;
1560
1561 rc = decode_query_downstream_devices_resp(
1562 response, responseMsg.size() - hdrSize, &resp_data);
1563
Unive Tien71e935c2024-11-25 17:21:43 +08001564 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001565 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1566 EXPECT_EQ(resp_data.downstream_device_update_supported,
1567 downstream_device_update_supported_resp);
1568 EXPECT_EQ(resp_data.number_of_downstream_devices,
1569 number_of_downstream_devices_resp);
1570 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1571 max_number_of_downstream_devices_resp);
1572 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1573}
1574
1575TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1576{
1577 uint8_t completion_code_resp = PLDM_SUCCESS;
1578 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1579 uint16_t number_of_downstream_devices_resp = 1;
1580 uint16_t max_number_of_downstream_devices_resp = 1;
1581 /** Capabilities of updating downstream devices
1582 * FDP supports downstream devices dynamically attached [Bit position 0] &
1583 * FDP supports downstream devices dynamically removed [Bit position 1]
1584 */
1585 bitfield32_t capabilities_resp = {.value = 0x0002};
1586 int rc;
1587
1588 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1589 responseMsg{};
1590
Andrew Jefferya1896962025-03-03 21:41:25 +10301591 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301592 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1593 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301594 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001595 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1596 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1597 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1598 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1599 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301600 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001601
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301602 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001603 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1604 struct pldm_query_downstream_devices_resp resp_data;
1605
1606 rc = decode_query_downstream_devices_resp(
1607 response, responseMsg.size() - hdrSize, &resp_data);
1608
Unive Tien71e935c2024-11-25 17:21:43 +08001609 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001610}
1611
1612TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1613{
1614 uint8_t completion_code_resp = PLDM_SUCCESS;
1615 uint8_t downstream_device_update_supported_resp =
1616 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1617 uint16_t number_of_downstream_devices_resp = 1;
1618 uint16_t max_number_of_downstream_devices_resp = 1;
1619 /** Capabilities of updating downstream devices
1620 * FDP supports downstream devices dynamically attached [Bit position 0] &
1621 * FDP supports downstream devices dynamically removed [Bit position 1]
1622 */
1623 bitfield32_t capabilities_resp = {.value = 0x0002};
1624 int rc;
1625
1626 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1627 2 /* Inject error length*/>
1628 responseMsg{};
1629
Andrew Jefferya1896962025-03-03 21:41:25 +10301630 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301631 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1632 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301633 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001634
1635 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1636 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1637 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1638 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1639 // Inject error value
1640 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301641 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001642
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301643 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001644 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1645 struct pldm_query_downstream_devices_resp resp_data;
1646
1647 rc = decode_query_downstream_devices_resp(
1648 response, responseMsg.size() - hdrSize, &resp_data);
1649
Unive Tien71e935c2024-11-25 17:21:43 +08001650 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001651}
1652
Chris Wang458475a2024-03-26 17:59:19 +08001653TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1654{
1655 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301656 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1657 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001658 constexpr pldm_query_downstream_identifiers_req params_req{
1659 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001660
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001661 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1662 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001663 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301664 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1665 ElementsAreArray<uint8_t>(
1666 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001667}
1668
1669TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1670{
1671 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001672 constexpr pldm_query_downstream_identifiers_req params_req{
1673 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1674 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1675 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001676 constexpr size_t payload_length =
1677 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1678 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301679 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001680 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1681
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001682 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1683 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001684 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001685
1686 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001687 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001688 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001689
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001690 rc = encode_query_downstream_identifiers_req(
1691 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001692 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001693}
1694
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301695TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001696{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301697 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1698 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1699 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1700 constexpr uint32_t downstream_devices_length_resp = 0;
1701 constexpr uint16_t number_of_downstream_devices_resp = 0;
1702
1703 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1704 struct pldm_query_downstream_identifiers_resp resp_data = {};
1705 struct pldm_downstream_device_iter devs;
Andrew Jefferya1896962025-03-03 21:41:25 +10301706 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301707 int rc = 0;
1708
1709 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1710 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1711 ASSERT_EQ(rc, 0);
1712
1713 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1714 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1715 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1716 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1717 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1718
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301719 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301720
1721 rc = decode_query_downstream_identifiers_resp(
1722 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1723 &devs);
1724
Unive Tien71e935c2024-11-25 17:21:43 +08001725 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301726 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1727 EXPECT_EQ(resp_data.next_data_transfer_handle,
1728 next_data_transfer_handle_resp);
1729 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1730 EXPECT_EQ(resp_data.downstream_devices_length,
1731 downstream_devices_length_resp);
1732 EXPECT_EQ(resp_data.number_of_downstream_devices,
1733 number_of_downstream_devices_resp);
1734}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301735
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301736TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1737{
1738 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1739 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1740 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1741 constexpr uint32_t downstream_devices_length_resp = 0;
1742 constexpr uint16_t number_of_downstream_devices_resp = 1;
1743
1744 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1745 struct pldm_query_downstream_identifiers_resp resp = {};
1746 struct pldm_downstream_device_iter devs;
1747 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301748 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301749 int rc = 0;
1750
1751 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1752 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1753 ASSERT_EQ(rc, 0);
1754
1755 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1756 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1757 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1758 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1759 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1760
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301761 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301762
1763 rc = decode_query_downstream_identifiers_resp(
1764 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001765 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301766
1767 foreach_pldm_downstream_device(devs, dev, rc)
1768 {
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10301769 FAIL();
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301770 }
1771 ASSERT_NE(rc, 0);
1772}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301773
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301774TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1775{
1776 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301777 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001778 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1779 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1780 const uint32_t downstream_devices_length_resp =
1781 htole32(downstreamDevicesLen);
1782 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301783 constexpr size_t payloadLen =
1784 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001785
Andrew Jefferydec237b2024-11-08 14:33:45 +10301786 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301787 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301788 struct pldm_downstream_device_iter devs;
1789 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301790 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301791 int rc = 0;
1792
1793 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1794 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001795
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301796 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001797 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1798 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1799 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1800 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1801
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301802 /* Downstream device */
1803 pldm_msgbuf_insert_uint16(buf, 1);
1804 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001805
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301806 /* Device descriptor */
1807 pldm_msgbuf_insert_uint16(buf, 1);
1808 pldm_msgbuf_insert_uint16(buf, 4);
1809 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001810
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301811 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301812
1813 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1814 &resp_data, &devs);
1815
Unive Tien71e935c2024-11-25 17:21:43 +08001816 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301817 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001818 EXPECT_EQ(resp_data.next_data_transfer_handle,
1819 next_data_transfer_handle_resp);
1820 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1821 EXPECT_EQ(resp_data.downstream_devices_length,
1822 downstream_devices_length_resp);
1823 EXPECT_EQ(resp_data.number_of_downstream_devices,
1824 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301825
1826 foreach_pldm_downstream_device(devs, dev, rc)
1827 {
1828 struct pldm_descriptor desc;
1829
1830 EXPECT_EQ(dev.downstream_device_index, 1);
1831 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1832
1833 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1834 {
1835 static const uint32_t dmtf = htole32(412);
1836 EXPECT_EQ(desc.descriptor_type, 1);
1837 EXPECT_EQ(desc.descriptor_length, 4);
1838 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1839 }
1840 ASSERT_EQ(rc, 0);
1841 }
1842 ASSERT_EQ(rc, 0);
1843}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301844
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301845constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1846constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1847const uint32_t iana_pen_openbmc = htole16(49871u);
1848const uint32_t iana_pen_dmtf = htole16(412u);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301849
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301850TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1851{
1852 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1853 {0, 1},
1854 {1, 1},
1855 }};
1856
1857 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1858 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1859 &iana_pen_dmtf},
1860 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1861 &iana_pen_openbmc},
1862 }};
1863
1864 constexpr uint32_t downstream_devices_len = 22;
1865 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1866 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1867 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1868 const uint32_t downstream_devices_length_resp =
1869 htole32(downstream_devices_len);
1870 constexpr uint16_t number_of_downstream_devices_resp = 2;
1871 constexpr size_t payloadLen =
1872 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1873
Patrick Williamsf37edd72024-12-18 11:22:58 -05001874 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301875 PLDM_MSG_DEFINE_P(response, payloadLen);
1876 struct pldm_downstream_device_iter devs;
1877 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301878 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301879 int rc = 0;
1880
1881 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1882 ASSERT_EQ(rc, 0);
1883
1884 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1885 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1886 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1887 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1888 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1889
1890 /* Downstream device */
1891 pldm_msgbuf_insert_uint16(buf, 0);
1892 pldm_msgbuf_insert_uint8(buf, 1);
1893
1894 /* Device descriptor */
1895 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1896 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1897 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1898
1899 /* Downstream device */
1900 pldm_msgbuf_insert_uint16(buf, 1);
1901 pldm_msgbuf_insert_uint8(buf, 1);
1902
1903 /* Device descriptor */
1904 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1905 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1906 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1907
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301908 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301909
1910 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1911 &resp_data, &devs);
1912
Unive Tien71e935c2024-11-25 17:21:43 +08001913 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301914 EXPECT_EQ(resp_data.number_of_downstream_devices,
1915 number_of_downstream_devices_resp);
1916
1917 size_t devIndex = 0;
1918 size_t descIndex = 0;
1919 foreach_pldm_downstream_device(devs, dev, rc)
1920 {
1921 struct pldm_descriptor desc;
1922
1923 ASSERT_LT(devIndex, expected_devices.size());
1924
1925 const struct pldm_downstream_device* expectedDev =
1926 &expected_devices[devIndex];
1927
1928 EXPECT_EQ(dev.downstream_device_index,
1929 expectedDev->downstream_device_index);
1930 EXPECT_EQ(dev.downstream_descriptor_count,
1931 expectedDev->downstream_descriptor_count);
1932
1933 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1934 {
1935 ASSERT_LT(descIndex, expected_descriptors.size());
1936
1937 const struct pldm_descriptor* expectedDesc =
1938 &expected_descriptors[descIndex];
1939
1940 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1941 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1942 EXPECT_EQ(memcmp(desc.descriptor_data,
1943 expectedDesc->descriptor_data,
1944 expectedDesc->descriptor_length),
1945 0);
1946
1947 descIndex++;
1948 }
1949 ASSERT_EQ(rc, 0);
1950 EXPECT_EQ(descIndex, 1 * devIndex + 1);
1951
1952 devIndex++;
1953 }
1954 ASSERT_EQ(rc, 0);
1955 EXPECT_EQ(devIndex, 2);
1956}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301957
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301958TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
1959{
1960 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1961 {0, 2},
1962 {1, 1},
1963 }};
1964
1965 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
1966 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1967 &iana_pen_dmtf},
1968 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1969 &iana_pen_openbmc},
1970 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1971 &iana_pen_dmtf},
1972 }};
1973
1974 constexpr uint32_t downstream_devices_len = 30;
1975 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1976 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1977 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1978 const uint32_t downstream_devices_length_resp =
1979 htole32(downstream_devices_len);
1980 constexpr uint16_t number_of_downstream_devices_resp = 2;
1981 constexpr size_t payloadLen =
1982 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1983
Patrick Williamsf37edd72024-12-18 11:22:58 -05001984 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301985 PLDM_MSG_DEFINE_P(response, payloadLen);
1986 struct pldm_downstream_device_iter devs;
1987 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301988 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301989 int rc = 0;
1990
1991 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1992 ASSERT_EQ(rc, 0);
1993
1994 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1995 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1996 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1997 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1998 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1999
2000 /* Downstream device */
2001 pldm_msgbuf_insert_uint16(buf, 0);
2002 pldm_msgbuf_insert_uint8(buf, 2);
2003
2004 /* Device descriptor */
2005 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2006 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2007 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2008
2009 /* Device descriptor */
2010 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2011 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2012 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2013
2014 /* Downstream device */
2015 pldm_msgbuf_insert_uint16(buf, 1);
2016 pldm_msgbuf_insert_uint8(buf, 1);
2017
2018 /* Device descriptor */
2019 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2020 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2021 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2022
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302023 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302024
2025 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2026 &resp_data, &devs);
2027
Unive Tien71e935c2024-11-25 17:21:43 +08002028 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302029 EXPECT_EQ(resp_data.number_of_downstream_devices,
2030 number_of_downstream_devices_resp);
2031
2032 size_t devIndex = 0;
2033 size_t descIndex = 0;
2034 foreach_pldm_downstream_device(devs, dev, rc)
2035 {
2036 struct pldm_descriptor desc;
2037
2038 ASSERT_LT(devIndex, expected_devices.size());
2039
2040 const struct pldm_downstream_device* expectedDev =
2041 &expected_devices[devIndex];
2042
2043 EXPECT_EQ(dev.downstream_device_index,
2044 expectedDev->downstream_device_index);
2045 EXPECT_EQ(dev.downstream_descriptor_count,
2046 expectedDev->downstream_descriptor_count);
2047
2048 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2049 {
2050 ASSERT_LT(descIndex, expected_descriptors.size());
2051
2052 const struct pldm_descriptor* expectedDesc =
2053 &expected_descriptors[descIndex];
2054
2055 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2056 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2057 EXPECT_EQ(memcmp(desc.descriptor_data,
2058 expectedDesc->descriptor_data,
2059 expectedDesc->descriptor_length),
2060 0);
2061
2062 descIndex++;
2063 }
2064 ASSERT_EQ(rc, 0);
2065
2066 devIndex++;
2067 }
2068 ASSERT_EQ(rc, 0);
2069 EXPECT_EQ(devIndex, 2);
2070 EXPECT_EQ(descIndex, 3);
2071}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302072
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302073TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2074{
2075 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2076 {0, 1},
2077 {1, 2},
2078 }};
2079
2080 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2081 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2082 &iana_pen_dmtf},
2083 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2084 &iana_pen_openbmc},
2085 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2086 &iana_pen_dmtf},
2087 }};
2088
2089 constexpr uint32_t downstream_devices_len = 30;
2090 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2091 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2092 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2093 const uint32_t downstream_devices_length_resp =
2094 htole32(downstream_devices_len);
2095 constexpr uint16_t number_of_downstream_devices_resp = 2;
2096 constexpr size_t payloadLen =
2097 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2098
Patrick Williamsf37edd72024-12-18 11:22:58 -05002099 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302100 PLDM_MSG_DEFINE_P(response, payloadLen);
2101 struct pldm_downstream_device_iter devs;
2102 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302103 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302104 int rc = 0;
2105
2106 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2107 ASSERT_EQ(rc, 0);
2108
2109 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2110 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2111 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2112 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2113 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2114
2115 /* Downstream device */
2116 pldm_msgbuf_insert_uint16(buf, 0);
2117 pldm_msgbuf_insert_uint8(buf, 1);
2118
2119 /* Device descriptor */
2120 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2121 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2122 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2123
2124 /* Downstream device */
2125 pldm_msgbuf_insert_uint16(buf, 1);
2126 pldm_msgbuf_insert_uint8(buf, 2);
2127
2128 /* Device descriptor */
2129 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2130 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2131 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2132
2133 /* Device descriptor */
2134 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2135 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2136 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2137
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302138 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302139
2140 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2141 &resp_data, &devs);
2142
Unive Tien71e935c2024-11-25 17:21:43 +08002143 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302144 EXPECT_EQ(resp_data.number_of_downstream_devices,
2145 number_of_downstream_devices_resp);
2146
2147 size_t devIndex = 0;
2148 size_t descIndex = 0;
2149 foreach_pldm_downstream_device(devs, dev, rc)
2150 {
2151 struct pldm_descriptor desc;
2152
2153 ASSERT_LT(devIndex, expected_devices.size());
2154
2155 const struct pldm_downstream_device* expectedDev =
2156 &expected_devices[devIndex];
2157
2158 EXPECT_EQ(dev.downstream_device_index,
2159 expectedDev->downstream_device_index);
2160 EXPECT_EQ(dev.downstream_descriptor_count,
2161 expectedDev->downstream_descriptor_count);
2162
2163 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2164 {
2165 ASSERT_LT(descIndex, expected_descriptors.size());
2166
2167 const struct pldm_descriptor* expectedDesc =
2168 &expected_descriptors[descIndex];
2169
2170 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2171 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2172 EXPECT_EQ(memcmp(desc.descriptor_data,
2173 expectedDesc->descriptor_data,
2174 expectedDesc->descriptor_length),
2175 0);
2176
2177 descIndex++;
2178 }
2179 ASSERT_EQ(rc, 0);
2180
2181 devIndex++;
2182 }
2183 ASSERT_EQ(rc, 0);
2184 EXPECT_EQ(devIndex, 2);
2185 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002186}
2187
2188TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2189{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302190 constexpr size_t payloadLen = sizeof(uint8_t);
2191
Chris Wang458475a2024-03-26 17:59:19 +08002192 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302193 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302194 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002195
2196 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302197 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2198 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002199 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002200
2201 // Test not PLDM_SUCCESS completion code
2202 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302203 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2204 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002205 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002206 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2207
2208 // Test payload length less than minimum length
2209 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302210 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2211 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002212
Unive Tien71e935c2024-11-25 17:21:43 +08002213 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002214}
2215
2216TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2217{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302218 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002219 // 1 descriptor
2220 constexpr uint32_t actualDownstreamDevicesLen = 9;
2221 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2222 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2223 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302224 constexpr uint16_t number_of_downstream_devices_resp = 1;
2225 constexpr size_t payloadLen =
2226 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2227 actualDownstreamDevicesLen;
2228
Chris Wang458475a2024-03-26 17:59:19 +08002229 const uint32_t downstream_devices_length_resp =
2230 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002231
Andrew Jefferydec237b2024-11-08 14:33:45 +10302232 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302233 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302234 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302235 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302236 void* devicesStart = NULL;
2237 size_t devicesLen;
2238 int rc = 0;
2239
2240 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302241 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002242
2243 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2244 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2245 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2246 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2247 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302248 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002249
Andrew Jefferya1896962025-03-03 21:41:25 +10302250 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2251
Chris Wang458475a2024-03-26 17:59:19 +08002252 /** Filling descriptor data, the correctness of the downstream devices data
2253 * is not checked in this test case so filling with 0xff
2254 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302255 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2256 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002257
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302258 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2259 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002260 0);
Chris Wang458475a2024-03-26 17:59:19 +08002261}
2262
2263TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2264{
2265 constexpr uint32_t actualDownstreamDevicesLen = 0;
2266 constexpr uint16_t number_of_downstream_devices_resp = 1;
2267 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2268 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2269 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302270 constexpr size_t payloadLen =
2271 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2272
Chris Wang458475a2024-03-26 17:59:19 +08002273 const uint32_t downstream_devices_length_resp =
2274 htole32(actualDownstreamDevicesLen);
2275
Andrew Jefferydec237b2024-11-08 14:33:45 +10302276 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302277 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302278 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302279 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302280 int rc = 0;
2281
2282 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2283 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002284
2285 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2286 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2287 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2288 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2289 // Inject error buffer size
2290 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
Andrew Jefferya1896962025-03-03 21:41:25 +10302291 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang458475a2024-03-26 17:59:19 +08002292
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302293 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2294 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002295
Unive Tien71e935c2024-11-25 17:21:43 +08002296 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002297}
2298
Chris Wangb6ef35b2024-07-03 09:35:42 +08002299TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2300{
2301 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302302 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002303 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002304 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302305 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002306 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302307 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002308 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2309
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302310 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002311 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002312 EXPECT_EQ(rc, 0);
2313
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302314 std::array<uint8_t,
2315 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002316 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2317 EXPECT_EQ(requestMsg, expectedReq);
2318}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002319
Chris Wangb6ef35b2024-07-03 09:35:42 +08002320TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2321{
2322 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002323 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302324 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002325 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002326 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302327 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002328 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302329 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002330 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2331
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302332 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002333 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002334 EXPECT_EQ(rc, -EBADMSG);
2335}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002336
Chris Wangb6ef35b2024-07-03 09:35:42 +08002337TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2338{
2339 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002340 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302341 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Andrew Jeffery53b08672025-03-04 12:26:18 +10302342 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002343 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302344 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
Chris Wangb6ef35b2024-07-03 09:35:42 +08002345 1 /* inject erro length*/;
2346
2347 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302348 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002349 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2350
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302351 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002352 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002353 EXPECT_EQ(rc, -EOVERFLOW);
2354}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002355
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302356TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002357{
Chris Wangb6ef35b2024-07-03 09:35:42 +08002358 constexpr uint16_t downstreamDeviceCount = 1;
2359 constexpr uint8_t activeComponentVersionStringLength = 8;
2360 constexpr uint8_t pendingComponentVersionStringLength = 8;
2361 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302362 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002363 activeComponentVersionStringLength +
2364 pendingComponentVersionStringLength;
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302365 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002366 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2367 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2368 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302369 constexpr size_t payload_len =
2370 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2371 downstreamDeviceParamTableLen;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002372
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302373 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302374 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302375 int rc = 0;
2376
2377 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302378 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002379
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302380 // Table 24
2381 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002382 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2383 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302384
2385 // Table 25
Chris Wangb6ef35b2024-07-03 09:35:42 +08002386 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2387 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2388
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302389 // Table 26
2390 pldm_msgbuf_insert_uint16(buf, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002391
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302392 // - Active metadata
2393 pldm_msgbuf_insert_uint32(buf, 0);
2394 pldm_msgbuf_insert_uint8(buf, 1);
2395 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2396 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2397 ASSERT_EQ(rc, 0);
2398
2399 // - Pending metadata
2400 pldm_msgbuf_insert_uint32(buf, 0);
2401 pldm_msgbuf_insert_uint8(buf, 1);
2402 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2403 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2404 ASSERT_EQ(rc, 0);
2405
2406 // - Methods and capabilities
2407 pldm_msgbuf_insert_uint16(buf, 1);
2408 pldm_msgbuf_insert_uint32(buf, 0);
2409
2410 // - Version strings
2411 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2412 "abcdefgh", 8);
2413 ASSERT_EQ(rc, 0);
2414 rc = pldm__msgbuf_insert_array_void(
2415 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2416 ASSERT_EQ(rc, 0);
2417
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302418 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302419 ASSERT_EQ(rc, 0);
2420
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302421 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302422 struct pldm_downstream_device_parameters_iter iter = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002423
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302424 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2425 &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002426
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302427 ASSERT_EQ(rc, 0);
2428 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002429 EXPECT_EQ(resp_data.next_data_transfer_handle,
2430 next_data_transfer_handle_resp);
2431 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2432 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302433
2434 struct pldm_downstream_device_parameters_entry entry;
2435 size_t entries = 0;
2436 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2437 {
2438 EXPECT_EQ(entry.downstream_device_index, 0);
2439 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2440 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2441 EXPECT_EQ(entry.active_comp_ver_str_len,
2442 activeComponentVersionStringLength);
2443 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2444 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2445 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2446 EXPECT_EQ(entry.pending_comp_ver_str_len,
2447 pendingComponentVersionStringLength);
2448 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2449 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2450 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2451 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2452 entry.active_comp_ver_str_len));
2453 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2454 entry.pending_comp_ver_str_len));
2455 entries++;
2456 }
2457 EXPECT_EQ(rc, 0);
2458 EXPECT_EQ(entries, 1);
2459}
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302460
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302461TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2462{
2463 /** Count is not fixed here taking it as 1, and the downstream device's
2464 * version strings length are set to 8
2465 */
2466 constexpr uint16_t downstreamDeviceCount = 2;
2467 constexpr uint8_t activeComponentVersionStringLength = 8;
2468 constexpr uint8_t pendingComponentVersionStringLength = 9;
2469 constexpr size_t downstreamDeviceParamTableLen =
2470 static_cast<size_t>(downstreamDeviceCount *
2471 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2472 activeComponentVersionStringLength +
2473 pendingComponentVersionStringLength));
2474 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2475 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2476 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2477 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2478 constexpr size_t payload_len =
2479 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2480 downstreamDeviceParamTableLen;
2481
2482 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302483 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302484 int rc = 0;
2485
2486 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302487 ASSERT_EQ(rc, 0);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302488
2489 // Table 24
2490 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2491 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2492 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2493
2494 // Table 25
2495 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2496 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2497
2498 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2499 table = {{{
2500 0,
2501 0,
2502 1,
2503 8,
2504 "20241206",
2505 0,
2506 1,
2507 9,
2508 "20241209",
2509 {1},
2510 {0},
2511 "active_0",
2512 "pending_0",
2513 },
2514 {
2515 1,
2516 0,
2517 1,
2518 8,
2519 "20241209",
2520 0,
2521 1,
2522 9,
2523 "20241206",
2524 {1},
2525 {0},
2526 "active_1",
2527 "pending_1",
2528 }}};
2529 for (const auto& e : table)
2530 {
2531 // Table 26
2532 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2533
2534 // - Active metadata
2535 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2536 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2537 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2538 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2539 sizeof(e.active_comp_release_date));
2540 ASSERT_EQ(rc, 0);
2541
2542 // - Pending metadata
2543 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2544 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2545 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2546 rc =
2547 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2548 sizeof(e.pending_comp_release_date));
2549 ASSERT_EQ(rc, 0);
2550
2551 // - Methods and capabilities
2552 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2553 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2554
2555 // - Version strings
2556 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2557 e.active_comp_ver_str,
2558 e.active_comp_ver_str_len);
2559 ASSERT_EQ(rc, 0);
2560 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2561 e.pending_comp_ver_str,
2562 e.pending_comp_ver_str_len);
2563 ASSERT_EQ(rc, 0);
2564 }
2565
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302566 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302567 ASSERT_EQ(rc, 0);
2568
2569 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2570 struct pldm_downstream_device_parameters_iter iter = {};
2571
2572 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2573 &resp_data, &iter);
2574
2575 ASSERT_EQ(rc, 0);
2576 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2577 EXPECT_EQ(resp_data.next_data_transfer_handle,
2578 next_data_transfer_handle_resp);
2579 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2580 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2581
2582 struct pldm_downstream_device_parameters_entry entry;
2583 size_t entryIndex = 0;
2584 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2585 {
2586 ASSERT_LE(entryIndex, table.size());
2587
2588 EXPECT_EQ(table[entryIndex].downstream_device_index,
2589 entry.downstream_device_index);
2590 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2591 entry.active_comp_comparison_stamp);
2592 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2593 entry.active_comp_ver_str_type);
2594 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2595 entry.active_comp_ver_str_len);
2596 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2597 &entry.active_comp_release_date[0]);
2598 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2599 entry.pending_comp_comparison_stamp);
2600 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2601 entry.pending_comp_ver_str_type);
2602 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2603 entry.pending_comp_ver_str_len);
2604 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2605 &entry.pending_comp_release_date[0]);
2606 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2607 entry.comp_activation_methods.value);
2608 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2609 entry.capabilities_during_update.value);
2610 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2611 entry.active_comp_ver_str,
2612 table[entryIndex].active_comp_ver_str_len));
2613 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2614 entry.pending_comp_ver_str,
2615 table[entryIndex].pending_comp_ver_str_len));
2616 entryIndex++;
2617 }
2618 EXPECT_EQ(rc, 0);
2619 EXPECT_EQ(entryIndex, table.size());
Chris Wangb6ef35b2024-07-03 09:35:42 +08002620}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002621
Chris Wangb6ef35b2024-07-03 09:35:42 +08002622TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2623{
2624 /** Count is not fixed here taking it as 1, and the downstream device's
2625 * version strings length are set to 8
2626 */
2627 constexpr uint16_t downstreamDeviceCount = 1;
2628 constexpr uint8_t activeComponentVersionStringLength = 8;
2629 constexpr uint8_t pendingComponentVersionStringLength = 8;
2630 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302631 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002632 activeComponentVersionStringLength +
2633 pendingComponentVersionStringLength;
2634 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2635 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2636 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2637 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2638
2639 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302640 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002641 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2642 responseMsg{};
2643
2644 int rc = 0;
2645
Andrew Jefferya1896962025-03-03 21:41:25 +10302646 PLDM_MSGBUF_DEFINE_P(buf);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002647 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2648 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10302649 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002650
2651 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2652 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2653 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2654 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2655 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
Andrew Jefferya1896962025-03-03 21:41:25 +10302656 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002657
2658 /** Filling paramter table, the correctness of the downstream devices data
2659 * is not checked in this test case so filling with 0xff
2660 */
2661 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302662 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002663 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2664 0xff);
2665
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302666 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002667 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302668 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302669 struct pldm_downstream_device_parameters_iter iter;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002670
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302671 rc = decode_get_downstream_firmware_parameters_resp(
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302672 response, responseMsg.size() - hdrSize, &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002673 EXPECT_EQ(rc, 0);
2674
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302675 struct pldm_downstream_device_parameters_entry entry;
2676 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2677 {
2678 FAIL();
2679 }
2680 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002681}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002682
Andrew Jeffery9c766792022-08-10 23:12:49 +09302683TEST(RequestUpdate, goodPathEncodeRequest)
2684{
2685 constexpr uint8_t instanceId = 1;
2686 constexpr uint32_t maxTransferSize = 512;
2687 constexpr uint16_t numOfComp = 3;
2688 constexpr uint8_t maxOutstandingTransferReq = 2;
2689 constexpr uint16_t pkgDataLen = 0x1234;
2690 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2691 constexpr uint8_t compImgSetVerStrLen =
2692 static_cast<uint8_t>(compImgSetVerStr.size());
2693 variable_field compImgSetVerStrInfo{};
2694 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302695 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302696 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2697 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2698
2699 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2700 compImgSetVerStrLen>
2701 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302702 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302703 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2704
2705 auto rc = encode_request_update_req(
2706 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2707 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2708 &compImgSetVerStrInfo, requestMsg,
2709 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2710 EXPECT_EQ(rc, PLDM_SUCCESS);
2711
2712 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2713 compImgSetVerStrLen>
2714 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2715 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2716 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2717 EXPECT_EQ(request, outRequest);
2718}
2719
2720TEST(RequestUpdate, errorPathEncodeRequest)
2721{
2722 constexpr uint8_t instanceId = 1;
2723 uint32_t maxTransferSize = 512;
2724 constexpr uint16_t numOfComp = 3;
2725 uint8_t maxOutstandingTransferReq = 2;
2726 constexpr uint16_t pkgDataLen = 0x1234;
2727 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2728 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2729 variable_field compImgSetVerStrInfo{};
2730 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302731 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302732 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2733 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2734
2735 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2736 compImgSetVerStr.size()>
2737 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302738 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302739 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2740
2741 auto rc = encode_request_update_req(
2742 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2743 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2744 requestMsg,
2745 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2746 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2747
2748 compImgSetVerStrInfo.ptr = nullptr;
2749 rc = encode_request_update_req(
2750 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2751 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2752 &compImgSetVerStrInfo, requestMsg,
2753 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2754 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2755 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302756 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302757 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2758
2759 rc = encode_request_update_req(
2760 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2761 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2762 &compImgSetVerStrInfo, nullptr,
2763 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2764 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2765
2766 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2767 maxOutstandingTransferReq, pkgDataLen,
2768 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2769 &compImgSetVerStrInfo, requestMsg, 0);
2770 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2771
2772 compImgSetVerStrLen = 0;
2773 rc = encode_request_update_req(
2774 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2775 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2776 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2777 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2778 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2779
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002780 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302781 rc = encode_request_update_req(
2782 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2783 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2784 &compImgSetVerStrInfo, nullptr,
2785 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2786 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2787 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2788
2789 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2790 rc = encode_request_update_req(
2791 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2792 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2793 &compImgSetVerStrInfo, nullptr,
2794 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2795 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2796 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2797
2798 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2799 rc = encode_request_update_req(
2800 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2801 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2802 &compImgSetVerStrInfo, nullptr,
2803 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2804 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2805 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2806
2807 rc = encode_request_update_req(
2808 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2809 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2810 &compImgSetVerStrInfo, nullptr,
2811 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2812 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2813}
2814
2815TEST(RequestUpdate, goodPathDecodeResponse)
2816{
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002817 /* Test a success completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302818 constexpr uint16_t fdMetaDataLen = 1024;
2819 constexpr uint8_t fdWillSendPkgData = 1;
2820 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2821 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2822
2823 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302824 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302825 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2826 uint8_t outCompletionCode = 0;
2827 uint16_t outFdMetaDataLen = 0;
2828 uint8_t outFdWillSendPkgData = 0;
2829
2830 auto rc = decode_request_update_resp(
2831 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2832 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2833 EXPECT_EQ(rc, PLDM_SUCCESS);
2834 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2835 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2836 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2837
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002838#ifdef LIBPLDM_API_TESTING
2839 /* Check the success roundtrip matches */
2840 PLDM_MSG_DEFINE_P(enc, 1000);
2841 size_t enc_payload_len = 1000;
2842 const struct pldm_request_update_resp resp_data = {
2843 .completion_code = PLDM_SUCCESS,
2844 .fd_meta_data_len = outFdMetaDataLen,
2845 .fd_will_send_pkg_data = outFdWillSendPkgData,
2846 };
2847 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2848 &enc_payload_len);
2849 EXPECT_EQ(rc, PLDM_SUCCESS);
2850 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2851 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2852 requestUpdateResponse1.end(), enc_buf + hdrSize));
2853 check_response(enc, PLDM_REQUEST_UPDATE);
2854#endif
2855
2856 /* Test a failure completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302857 outCompletionCode = 0;
2858 outFdMetaDataLen = 0;
2859 outFdWillSendPkgData = 0;
2860
2861 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2862 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2863 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302864 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302865 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2866 rc = decode_request_update_resp(
2867 responseMsg2, requestUpdateResponse2.size() - hdrSize,
2868 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2869 EXPECT_EQ(rc, PLDM_SUCCESS);
2870 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2871}
2872
2873TEST(RequestUpdate, errorPathDecodeResponse)
2874{
2875 constexpr std::array<uint8_t,
2876 hdrSize + sizeof(pldm_request_update_resp) - 1>
2877 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2878
2879 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302880 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302881 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2882 uint8_t outCompletionCode = 0;
2883 uint16_t outFdMetaDataLen = 0;
2884 uint8_t outFdWillSendPkgData = 0;
2885
2886 auto rc = decode_request_update_resp(
2887 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2888 &outFdMetaDataLen, &outFdWillSendPkgData);
2889 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2890
2891 rc = decode_request_update_resp(
2892 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2893 &outFdMetaDataLen, &outFdWillSendPkgData);
2894 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2895
2896 rc = decode_request_update_resp(
2897 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2898 nullptr, &outFdWillSendPkgData);
2899 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2900
2901 rc = decode_request_update_resp(
2902 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2903 &outFdMetaDataLen, nullptr);
2904 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2905
2906 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2907 &outFdMetaDataLen, &outFdWillSendPkgData);
2908 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2909
2910 rc = decode_request_update_resp(
2911 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2912 &outFdMetaDataLen, &outFdWillSendPkgData);
2913 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2914}
2915
2916TEST(PassComponentTable, goodPathEncodeRequest)
2917{
2918 constexpr uint8_t instanceId = 1;
2919 constexpr uint16_t compIdentifier = 400;
2920 constexpr uint8_t compClassificationIndex = 40;
2921 constexpr uint32_t compComparisonStamp = 0x12345678;
2922 constexpr std::string_view compVerStr = "0penBmcv1.1";
2923 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2924 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302925 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302926 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2927 compVerStrInfo.length = compVerStrLen;
2928
2929 std::array<uint8_t,
2930 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2931 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302932 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302933 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2934
2935 auto rc = encode_pass_component_table_req(
2936 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2937 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2938 compVerStrLen, &compVerStrInfo, requestMsg,
2939 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2940 EXPECT_EQ(rc, PLDM_SUCCESS);
2941
2942 std::array<uint8_t,
2943 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002944 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2945 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2946 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09302947 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002948
2949#ifdef LIBPLDM_API_TESTING
2950 /* Check the roundtrip */
2951 struct pldm_pass_component_table_req_full req;
2952 PLDM_MSG_DEFINE_P(dec, outRequest.size());
2953 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
2954 rc =
2955 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
2956 ASSERT_EQ(rc, 0);
2957
2958 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
2959 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
2960 EXPECT_EQ(req.comp_identifier, compIdentifier);
2961 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
2962 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
2963 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
2964 EXPECT_EQ(req.version.str_len, compVerStrLen);
2965 EXPECT_TRUE(std::equal(req.version.str_data,
2966 req.version.str_data + req.version.str_len,
2967 compVerStr.data()));
2968#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09302969}
2970
2971TEST(PassComponentTable, errorPathEncodeRequest)
2972{
2973 constexpr uint8_t instanceId = 1;
2974 constexpr uint16_t compIdentifier = 400;
2975 constexpr uint8_t compClassificationIndex = 40;
2976 constexpr uint32_t compComparisonStamp = 0x12345678;
2977 constexpr std::string_view compVerStr = "0penBmcv1.1";
2978 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2979 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302980 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302981 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2982 compVerStrInfo.length = compVerStrLen;
2983
2984 std::array<uint8_t,
2985 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2986 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302987 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302988 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2989
2990 auto rc = encode_pass_component_table_req(
2991 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2992 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2993 compVerStrLen, nullptr, requestMsg,
2994 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2995 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2996
2997 compVerStrInfo.ptr = nullptr;
2998 rc = encode_pass_component_table_req(
2999 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3000 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3001 compVerStrLen, &compVerStrInfo, requestMsg,
3002 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3003 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303004 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303005 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3006
3007 rc = encode_pass_component_table_req(
3008 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3009 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3010 compVerStrLen, &compVerStrInfo, nullptr,
3011 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3012 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3013
3014 rc = encode_pass_component_table_req(
3015 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3016 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3017 compVerStrLen, &compVerStrInfo, requestMsg,
3018 sizeof(pldm_pass_component_table_req));
3019 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3020
3021 rc = encode_pass_component_table_req(
3022 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3023 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3024 &compVerStrInfo, requestMsg,
3025 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3026 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3027
3028 rc = encode_pass_component_table_req(
3029 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3030 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3031 compVerStrLen - 1, &compVerStrInfo, requestMsg,
3032 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3033 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3034
3035 rc = encode_pass_component_table_req(
3036 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3037 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3038 compVerStrLen, &compVerStrInfo, requestMsg,
3039 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3040 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
3041
3042 rc = encode_pass_component_table_req(
3043 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3044 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3045 compVerStrLen, &compVerStrInfo, requestMsg,
3046 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3047 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3048}
3049
3050TEST(PassComponentTable, goodPathDecodeResponse)
3051{
3052 constexpr std::array<uint8_t,
3053 hdrSize + sizeof(pldm_pass_component_table_resp)>
3054 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3055 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303056 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303057 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3058
3059 uint8_t completionCode = 0;
3060 uint8_t compResp = 0;
3061 uint8_t compRespCode = 0;
3062
3063 auto rc = decode_pass_component_table_resp(
3064 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3065 &compResp, &compRespCode);
3066
3067 EXPECT_EQ(rc, PLDM_SUCCESS);
3068 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3069 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3070 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3071
3072 constexpr std::array<uint8_t,
3073 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003074 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303075 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303076 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303077 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3078 rc = decode_pass_component_table_resp(
3079 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3080 &compResp, &compRespCode);
3081
3082 EXPECT_EQ(rc, PLDM_SUCCESS);
3083 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3084 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3085 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3086
3087 constexpr std::array<uint8_t,
3088 hdrSize + sizeof(pldm_pass_component_table_resp)>
3089 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3090 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303091 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303092 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3093
3094 rc = decode_pass_component_table_resp(
3095 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3096 &compResp, &compRespCode);
3097
3098 EXPECT_EQ(rc, PLDM_SUCCESS);
3099 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3100}
3101
3102TEST(PassComponentTable, errorPathDecodeResponse)
3103{
3104 constexpr std::array<uint8_t,
3105 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3106 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3107 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303108 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303109 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3110
3111 uint8_t completionCode = 0;
3112 uint8_t compResp = 0;
3113 uint8_t compRespCode = 0;
3114
3115 auto rc = decode_pass_component_table_resp(
3116 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3117 &compResp, &compRespCode);
3118 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3119
3120 rc = decode_pass_component_table_resp(
3121 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3122 &compResp, &compRespCode);
3123 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3124
3125 rc = decode_pass_component_table_resp(
3126 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3127 &completionCode, nullptr, &compRespCode);
3128 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3129
3130 rc = decode_pass_component_table_resp(
3131 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3132 &completionCode, &compResp, nullptr);
3133 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3134
3135 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3136 &compResp, &compRespCode);
3137 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3138
3139 rc = decode_pass_component_table_resp(
3140 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3141 &completionCode, &compResp, &compRespCode);
3142 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3143
3144 constexpr std::array<uint8_t,
3145 hdrSize + sizeof(pldm_pass_component_table_resp)>
3146 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3147 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303148 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303149 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3150 rc = decode_pass_component_table_resp(
3151 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3152 &compResp, &compRespCode);
3153 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3154
3155 constexpr std::array<uint8_t,
3156 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003157 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303158 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303159 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303160 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3161 rc = decode_pass_component_table_resp(
3162 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3163 &compResp, &compRespCode);
3164 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3165
3166 constexpr std::array<uint8_t,
3167 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003168 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303169 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303170 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303171 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3172 rc = decode_pass_component_table_resp(
3173 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3174 &compResp, &compRespCode);
3175 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3176}
3177
3178TEST(UpdateComponent, goodPathEncodeRequest)
3179{
3180 constexpr uint8_t instanceId = 2;
3181 constexpr uint16_t compIdentifier = 500;
3182 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003183 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303184 constexpr uint32_t compImageSize = 4096;
3185 constexpr bitfield32_t updateOptionFlags{1};
3186 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3187 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3188 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303189 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303190 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3191 compVerStrInfo.length = compVerStrLen;
3192
3193 std::array<uint8_t,
3194 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3195 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303196 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303197 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3198
3199 auto rc = encode_update_component_req(
3200 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3201 compComparisonStamp, compImageSize, updateOptionFlags,
3202 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3203 sizeof(pldm_update_component_req) + compVerStrLen);
3204 EXPECT_EQ(rc, PLDM_SUCCESS);
3205
3206 std::array<uint8_t,
3207 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003208 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3209 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3210 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3211 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303212 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003213
3214#ifdef LIBPLDM_API_TESTING
3215 /* Check the roundtrip */
3216 struct pldm_update_component_req_full req;
3217 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3218 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3219 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3220 ASSERT_EQ(rc, 0);
3221
3222 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3223 EXPECT_EQ(req.comp_identifier, compIdentifier);
3224 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3225 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3226 EXPECT_EQ(req.comp_image_size, compImageSize);
3227 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3228 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3229 EXPECT_EQ(req.version.str_len, compVerStrLen);
3230 EXPECT_TRUE(std::equal(req.version.str_data,
3231 req.version.str_data + req.version.str_len,
3232 compVerStr.data()));
3233#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303234}
3235
3236TEST(UpdateComponent, errorPathEncodeRequest)
3237{
3238 constexpr uint8_t instanceId = 2;
3239 constexpr uint16_t compIdentifier = 500;
3240 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003241 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303242 constexpr uint32_t compImageSize = 4096;
3243 constexpr bitfield32_t updateOptionFlags{1};
3244 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3245 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3246 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303247 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303248 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3249 compVerStrInfo.length = compVerStrLen;
3250
3251 std::array<uint8_t,
3252 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3253 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303254 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303255 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3256
3257 auto rc = encode_update_component_req(
3258 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3259 compComparisonStamp, compImageSize, updateOptionFlags,
3260 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3261 sizeof(pldm_update_component_req) + compVerStrLen);
3262 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3263
3264 compVerStrInfo.ptr = nullptr;
3265 rc = encode_update_component_req(
3266 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3267 compComparisonStamp, compImageSize, updateOptionFlags,
3268 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3269 sizeof(pldm_update_component_req) + compVerStrLen);
3270 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303271 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303272 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3273
3274 rc = encode_update_component_req(
3275 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3276 compComparisonStamp, compImageSize, updateOptionFlags,
3277 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3278 sizeof(pldm_update_component_req) + compVerStrLen);
3279 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3280
3281 rc = encode_update_component_req(
3282 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3283 compComparisonStamp, compImageSize, updateOptionFlags,
3284 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3285 sizeof(pldm_update_component_req));
3286 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3287
3288 rc = encode_update_component_req(
3289 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3290 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3291 compVerStrLen, &compVerStrInfo, requestMsg,
3292 sizeof(pldm_update_component_req) + compVerStrLen);
3293 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3294
3295 rc = encode_update_component_req(
3296 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3297 compComparisonStamp, compImageSize, updateOptionFlags,
3298 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3299 sizeof(pldm_update_component_req) + compVerStrLen);
3300 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3301
3302 rc = encode_update_component_req(
3303 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3304 compComparisonStamp, compImageSize, updateOptionFlags,
3305 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3306 sizeof(pldm_update_component_req) + compVerStrLen);
3307 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3308
3309 rc = encode_update_component_req(
3310 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3311 compComparisonStamp, compImageSize, updateOptionFlags,
3312 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3313 sizeof(pldm_update_component_req) + compVerStrLen);
3314 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3315}
3316
3317TEST(UpdateComponent, goodPathDecodeResponse)
3318{
3319 constexpr std::bitset<32> forceUpdateComp{1};
3320 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3321 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3322 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3323 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3324 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303325 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303326 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3327
3328 uint8_t completionCode = 0;
3329 uint8_t compCompatibilityResp = 0;
3330 uint8_t compCompatibilityRespCode = 0;
3331 bitfield32_t updateOptionFlagsEnabled{};
3332 uint16_t timeBeforeReqFWData = 0;
3333
3334 auto rc = decode_update_component_resp(
3335 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3336 &compCompatibilityResp, &compCompatibilityRespCode,
3337 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3338
3339 EXPECT_EQ(rc, PLDM_SUCCESS);
3340 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3341 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3342 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3343 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3344 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3345
3346 constexpr std::bitset<32> noFlags{};
3347 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3348 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3349 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3351 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303352 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303353 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3354 rc = decode_update_component_resp(
3355 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3356 &compCompatibilityResp, &compCompatibilityRespCode,
3357 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3358
3359 EXPECT_EQ(rc, PLDM_SUCCESS);
3360 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3361 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3362 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3363 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3364 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3365
3366 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3367 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3368 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303369 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303370 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3371
3372 rc = decode_update_component_resp(
3373 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3374 &compCompatibilityResp, &compCompatibilityRespCode,
3375 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3376
3377 EXPECT_EQ(rc, PLDM_SUCCESS);
3378 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3379}
3380
3381TEST(UpdateComponent, errorPathDecodeResponse)
3382{
3383 constexpr std::array<uint8_t,
3384 hdrSize + sizeof(pldm_update_component_resp) - 1>
3385 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3386 0x00, 0x00, 0x00, 0x00, 0x00};
3387 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303388 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303389 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3390
3391 uint8_t completionCode = 0;
3392 uint8_t compCompatibilityResp = 0;
3393 uint8_t compCompatibilityRespCode = 0;
3394 bitfield32_t updateOptionFlagsEnabled{};
3395 uint16_t timeBeforeReqFWData = 0;
3396
3397 auto rc = decode_update_component_resp(
3398 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3399 &compCompatibilityResp, &compCompatibilityRespCode,
3400 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3401 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3402
3403 rc = decode_update_component_resp(
3404 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3405 &compCompatibilityResp, &compCompatibilityRespCode,
3406 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3407 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3408
3409 rc = decode_update_component_resp(
3410 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3411 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3412 &timeBeforeReqFWData);
3413 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3414
3415 rc = decode_update_component_resp(
3416 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3417 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3418 &timeBeforeReqFWData);
3419 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3420
3421 rc = decode_update_component_resp(
3422 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3423 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3424 &timeBeforeReqFWData);
3425 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3426
3427 rc = decode_update_component_resp(
3428 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3429 &compCompatibilityResp, &compCompatibilityRespCode,
3430 &updateOptionFlagsEnabled, nullptr);
3431 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3432
3433 rc = decode_update_component_resp(
3434 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3435 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3436 &timeBeforeReqFWData);
3437 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3438
3439 rc = decode_update_component_resp(
3440 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3441 &compCompatibilityResp, &compCompatibilityRespCode,
3442 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3443 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3444
3445 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3446 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3447 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3448 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303449 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303450 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3451 rc = decode_update_component_resp(
3452 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3453 &compCompatibilityResp, &compCompatibilityRespCode,
3454 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3455 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3456
3457 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003458 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303459 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3460 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303461 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303462 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3463 rc = decode_update_component_resp(
3464 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3465 &compCompatibilityResp, &compCompatibilityRespCode,
3466 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3467 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3468
3469 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003470 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303471 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3472 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303473 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303474 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3475 rc = decode_update_component_resp(
3476 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3477 &compCompatibilityResp, &compCompatibilityRespCode,
3478 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3479 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3480}
3481
3482TEST(RequestFirmwareData, goodPathDecodeRequest)
3483{
3484 constexpr uint32_t offset = 300;
3485 constexpr uint32_t length = 255;
3486 constexpr std::array<uint8_t,
3487 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003488 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3489 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303490 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303491 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3492
3493 uint32_t outOffset = 0;
3494 uint32_t outLength = 0;
3495 auto rc = decode_request_firmware_data_req(
3496 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3497 &outLength);
3498
3499 EXPECT_EQ(rc, PLDM_SUCCESS);
3500 EXPECT_EQ(outOffset, offset);
3501 EXPECT_EQ(outLength, length);
3502}
3503
3504TEST(RequestFirmwareData, errorPathDecodeRequest)
3505{
3506 constexpr std::array<uint8_t,
3507 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003508 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3509 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303510 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303511 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3512
3513 uint32_t outOffset = 0;
3514 uint32_t outLength = 0;
3515 auto rc = decode_request_firmware_data_req(
3516 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3517 &outLength);
3518 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3519
3520 rc = decode_request_firmware_data_req(
3521 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3522 &outLength);
3523 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3524
3525 rc = decode_request_firmware_data_req(
3526 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3527 nullptr);
3528 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3529
3530 rc = decode_request_firmware_data_req(
3531 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3532 &outLength);
3533 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3534
3535 rc = decode_request_firmware_data_req(
3536 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3537 &outLength);
3538 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3539}
3540
3541TEST(RequestFirmwareData, goodPathEncodeResponse)
3542{
3543 constexpr uint8_t instanceId = 3;
3544 constexpr uint8_t completionCode = PLDM_SUCCESS;
3545 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3546 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3547 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003548 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3549 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3550 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3551 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303552 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3553 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3554 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003555 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3556 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3557 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3558 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303559 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303560 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3561 auto rc = encode_request_firmware_data_resp(
3562 instanceId, completionCode, responseMsg1,
3563 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3564 EXPECT_EQ(rc, PLDM_SUCCESS);
3565 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3566
3567 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3568 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3569 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3570 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303571 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303572 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3573 rc = encode_request_firmware_data_resp(
3574 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3575 sizeof(completionCode));
3576 EXPECT_EQ(rc, PLDM_SUCCESS);
3577 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3578}
3579
3580TEST(RequestFirmwareData, errorPathEncodeResponse)
3581{
3582 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303583 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303584 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3585 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3586 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3587
3588 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3589 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3590}
3591
3592TEST(TransferComplete, goodPathDecodeRequest)
3593{
3594 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3595 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3596 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3597 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303598 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303599 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3600 uint8_t outTransferResult = 0;
3601
3602 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3603 &outTransferResult);
3604 EXPECT_EQ(rc, PLDM_SUCCESS);
3605 EXPECT_EQ(outTransferResult, transferResult);
3606
3607 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3608 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3609 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303610 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303611 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3612 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3613 &outTransferResult);
3614 EXPECT_EQ(rc, PLDM_SUCCESS);
3615 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3616}
3617
3618TEST(TransferComplete, errorPathDecodeRequest)
3619{
3620 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3621 0x00};
3622 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303623 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303624 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3625 uint8_t outTransferResult = 0;
3626
3627 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3628 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3629
3630 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3631 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3632
3633 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3634 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3635}
3636
3637TEST(TransferComplete, goodPathEncodeResponse)
3638{
3639 constexpr uint8_t instanceId = 4;
3640 constexpr uint8_t completionCode = PLDM_SUCCESS;
3641 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3642 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3643 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3644 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3645 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303646 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303647 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3648 auto rc = encode_transfer_complete_resp(
3649 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3650 EXPECT_EQ(rc, PLDM_SUCCESS);
3651 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3652
3653 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3654 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3655 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3656 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3657 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303658 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303659 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3660 rc = encode_transfer_complete_resp(instanceId,
3661 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3662 responseMsg2, sizeof(completionCode));
3663 EXPECT_EQ(rc, PLDM_SUCCESS);
3664 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3665}
3666
3667TEST(TransferComplete, errorPathEncodeResponse)
3668{
3669 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3670 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303671 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303672 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3673 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3674 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3675
3676 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3677 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3678}
3679
3680TEST(VerifyComplete, goodPathDecodeRequest)
3681{
3682 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3683 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3684 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3685 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303686 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303687 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3688 uint8_t outVerifyResult = 0;
3689
3690 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3691 &outVerifyResult);
3692 EXPECT_EQ(rc, PLDM_SUCCESS);
3693 EXPECT_EQ(outVerifyResult, verifyResult);
3694
3695 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3696 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3697 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303698 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303699 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3700 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3701 &outVerifyResult);
3702 EXPECT_EQ(rc, PLDM_SUCCESS);
3703 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3704}
3705
3706TEST(VerifyComplete, errorPathDecodeRequest)
3707{
3708 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3709 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303710 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303711 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3712 uint8_t outVerifyResult = 0;
3713
3714 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3715 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3716
3717 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3718 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3719
3720 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3721 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3722}
3723
3724TEST(VerifyComplete, goodPathEncodeResponse)
3725{
3726 constexpr uint8_t instanceId = 5;
3727 constexpr uint8_t completionCode = PLDM_SUCCESS;
3728 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3729 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3730 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3731 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3732 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303733 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303734 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3735 auto rc = encode_verify_complete_resp(instanceId, completionCode,
3736 responseMsg1, sizeof(completionCode));
3737 EXPECT_EQ(rc, PLDM_SUCCESS);
3738 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3739
3740 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3741 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3742 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3743 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3744 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303745 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303746 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3747 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3748 responseMsg2, sizeof(completionCode));
3749 EXPECT_EQ(rc, PLDM_SUCCESS);
3750 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3751}
3752
3753TEST(VerifyComplete, errorPathEncodeResponse)
3754{
3755 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3756 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303757 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303758 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3759 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3760 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3761
3762 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3763 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3764}
3765
3766TEST(ApplyComplete, goodPathDecodeRequest)
3767{
3768 constexpr uint8_t applyResult1 =
3769 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3770 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3771 constexpr std::bitset<16> compActivationModification1{0x30};
3772 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3773 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3774 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303775 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303776 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3777 uint8_t outApplyResult = 0;
3778 bitfield16_t outCompActivationModification{};
3779 auto rc = decode_apply_complete_req(
3780 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3781 &outCompActivationModification);
3782 EXPECT_EQ(rc, PLDM_SUCCESS);
3783 EXPECT_EQ(outApplyResult, applyResult1);
3784 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3785
3786 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3787 constexpr std::bitset<16> compActivationModification2{};
3788 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3789 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3790 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303791 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303792 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3793 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3794 &outApplyResult,
3795 &outCompActivationModification);
3796 EXPECT_EQ(rc, PLDM_SUCCESS);
3797 EXPECT_EQ(outApplyResult, applyResult2);
3798 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3799}
3800
3801TEST(ApplyComplete, errorPathDecodeRequest)
3802{
3803 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3804 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303805 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303806 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3807 uint8_t outApplyResult = 0;
3808 bitfield16_t outCompActivationModification{};
3809
3810 auto rc = decode_apply_complete_req(
3811 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3812 &outCompActivationModification);
3813 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3814
3815 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3816 nullptr, &outCompActivationModification);
3817 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3818
3819 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3820 &outApplyResult, nullptr);
3821 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3822
3823 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3824 &outCompActivationModification);
3825 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3826
3827 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3828 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3829 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303830 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303831 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3832 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3833 &outApplyResult,
3834 &outCompActivationModification);
3835 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3836}
3837
3838TEST(ApplyComplete, goodPathEncodeResponse)
3839{
3840 constexpr uint8_t instanceId = 6;
3841 constexpr uint8_t completionCode = PLDM_SUCCESS;
3842 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3843 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3844 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3845 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3846 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303847 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303848 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3849 auto rc = encode_apply_complete_resp(instanceId, completionCode,
3850 responseMsg1, sizeof(completionCode));
3851 EXPECT_EQ(rc, PLDM_SUCCESS);
3852 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3853
3854 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3855 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3856 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3857 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3858 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303859 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303860 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3861 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3862 responseMsg2, sizeof(completionCode));
3863 EXPECT_EQ(rc, PLDM_SUCCESS);
3864 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3865}
3866
3867TEST(ApplyComplete, errorPathEncodeResponse)
3868{
3869 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3870 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303871 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303872 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3873 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3874 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3875
3876 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3877 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3878}
3879
3880TEST(ActivateFirmware, goodPathEncodeRequest)
3881{
3882 constexpr uint8_t instanceId = 7;
3883
3884 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303885 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303886 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3887
3888 auto rc = encode_activate_firmware_req(
3889 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3890 sizeof(pldm_activate_firmware_req));
3891 EXPECT_EQ(rc, PLDM_SUCCESS);
3892
3893 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003894 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303895 EXPECT_EQ(request, outRequest);
3896}
3897
3898TEST(ActivateFirmware, errorPathEncodeRequest)
3899{
3900 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303901 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303902 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3903
3904 auto rc = encode_activate_firmware_req(
3905 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3906 sizeof(pldm_activate_firmware_req));
3907 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3908
3909 rc = encode_activate_firmware_req(
3910 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3911 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3912
3913 rc = encode_activate_firmware_req(0, 2, requestMsg,
3914 sizeof(pldm_activate_firmware_req));
3915 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3916}
3917
3918TEST(ActivateFirmware, goodPathDecodeResponse)
3919{
3920 constexpr uint16_t estimatedTimeForActivation100s = 100;
3921 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3922 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3923 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303924 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303925 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3926
3927 uint8_t completionCode = 0;
3928 uint16_t estimatedTimeForActivation = 0;
3929
3930 auto rc = decode_activate_firmware_resp(
3931 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3932 &estimatedTimeForActivation);
3933
3934 EXPECT_EQ(rc, PLDM_SUCCESS);
3935 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3936 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3937
3938 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3939 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3940 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303941 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303942 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3943
3944 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3945 &completionCode,
3946 &estimatedTimeForActivation);
3947
3948 EXPECT_EQ(rc, PLDM_SUCCESS);
3949 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3950}
3951
3952TEST(ActivateFirmware, errorPathDecodeResponse)
3953{
3954 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3955 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3956 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303957 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303958 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
3959
3960 uint8_t completionCode = 0;
3961 uint16_t estimatedTimeForActivation = 0;
3962
3963 auto rc = decode_activate_firmware_resp(
3964 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
3965 &estimatedTimeForActivation);
3966 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3967
3968 rc = decode_activate_firmware_resp(responseMsg,
3969 sizeof(pldm_activate_firmware_resp),
3970 nullptr, &estimatedTimeForActivation);
3971 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3972
3973 rc = decode_activate_firmware_resp(responseMsg,
3974 sizeof(pldm_activate_firmware_resp),
3975 &completionCode, nullptr);
3976 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3977
3978 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
3979 &estimatedTimeForActivation);
3980 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3981
3982 rc = decode_activate_firmware_resp(
3983 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
3984 &estimatedTimeForActivation);
3985 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3986}
3987
3988TEST(GetStatus, goodPathEncodeRequest)
3989{
3990 constexpr uint8_t instanceId = 8;
3991 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303992 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303993 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3994
3995 auto rc = encode_get_status_req(instanceId, requestMsg,
3996 PLDM_GET_STATUS_REQ_BYTES);
3997 EXPECT_EQ(rc, PLDM_SUCCESS);
3998
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003999 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304000 EXPECT_EQ(request, outRequest);
4001}
4002
4003TEST(GetStatus, errorPathEncodeRequest)
4004{
4005 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304006 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304007 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4008
4009 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4010 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4011
4012 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4013 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4014}
4015
4016TEST(GetStatus, goodPathDecodeResponse)
4017{
4018 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4019 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4020 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4021 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4022 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304023 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304024 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4025
4026 uint8_t completionCode = 0;
4027 uint8_t currentState = 0;
4028 uint8_t previousState = 0;
4029 uint8_t auxState = 0;
4030 uint8_t auxStateStatus = 0;
4031 uint8_t progressPercent = 0;
4032 uint8_t reasonCode = 0;
4033 bitfield32_t updateOptionFlagsEnabled{0};
4034
4035 auto rc = decode_get_status_resp(
4036 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4037 &currentState, &previousState, &auxState, &auxStateStatus,
4038 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4039
4040 EXPECT_EQ(rc, PLDM_SUCCESS);
4041 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4042 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4043 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4044 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4045 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4046 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4047 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4048 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4049
4050 // Bit position 0 - Force update of component – FD will perform a force
4051 // update of the component.
4052 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4053 constexpr uint8_t progressPercent2 = 50;
4054 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4055 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4056 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4057 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304058 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304059 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4060
4061 rc = decode_get_status_resp(
4062 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4063 &currentState, &previousState, &auxState, &auxStateStatus,
4064 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4065
4066 EXPECT_EQ(rc, PLDM_SUCCESS);
4067 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4068 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4069 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4070 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4071 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4072 EXPECT_EQ(progressPercent, progressPercent2);
4073 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4074 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4075
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004076#ifdef LIBPLDM_API_TESTING
4077 /* Check the roundtrip */
4078 PLDM_MSG_DEFINE_P(enc, 1000);
4079 size_t enc_payload_len = 1000;
4080 const struct pldm_get_status_resp status_enc = {
4081 .completion_code = PLDM_SUCCESS,
4082 .current_state = currentState,
4083 .previous_state = previousState,
4084 .aux_state = auxState,
4085 .aux_state_status = auxStateStatus,
4086 .progress_percent = progressPercent,
4087 .reason_code = reasonCode,
4088 .update_option_flags_enabled = updateOptionFlagsEnabled,
4089 };
4090 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4091 &enc_payload_len);
4092 EXPECT_EQ(rc, PLDM_SUCCESS);
4093 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4094 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4095 getStatusResponse2.end(), enc_buf + hdrSize));
4096 check_response(enc, PLDM_GET_STATUS);
4097#endif
4098
4099 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304100 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4101 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4102 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304103 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304104 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4105 rc = decode_get_status_resp(
4106 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4107 &currentState, &previousState, &auxState, &auxStateStatus,
4108 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4109 EXPECT_EQ(rc, PLDM_SUCCESS);
4110 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4111}
4112
4113TEST(GetStatus, errorPathDecodeResponse)
4114{
4115 uint8_t completionCode = 0;
4116 uint8_t currentState = 0;
4117 uint8_t previousState = 0;
4118 uint8_t auxState = 0;
4119 uint8_t auxStateStatus = 0;
4120 uint8_t progressPercent = 0;
4121 uint8_t reasonCode = 0;
4122 bitfield32_t updateOptionFlagsEnabled{0};
4123
4124 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4125 auto responseMsg1 =
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*>(getStatusResponse1.data());
4128
4129 auto rc = decode_get_status_resp(
4130 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4131 &currentState, &previousState, &auxState, &auxStateStatus,
4132 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4133 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4134
4135 rc = decode_get_status_resp(
4136 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4137 &currentState, &previousState, &auxState, &auxStateStatus,
4138 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4139 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4140
4141 rc = decode_get_status_resp(
4142 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4143 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4144 &reasonCode, &updateOptionFlagsEnabled);
4145 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4146
4147 rc = decode_get_status_resp(
4148 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4149 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4150 &reasonCode, &updateOptionFlagsEnabled);
4151 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4152
4153 rc = decode_get_status_resp(
4154 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4155 &currentState, &previousState, nullptr, &auxStateStatus,
4156 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4157 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4158
4159 rc = decode_get_status_resp(
4160 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4161 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4162 &reasonCode, &updateOptionFlagsEnabled);
4163 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4164
4165 rc = decode_get_status_resp(
4166 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4167 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4168 &reasonCode, &updateOptionFlagsEnabled);
4169 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4170
4171 rc = decode_get_status_resp(
4172 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4173 &currentState, &previousState, &auxState, &auxStateStatus,
4174 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4175 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4176
4177 rc = decode_get_status_resp(
4178 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4179 &currentState, &previousState, &auxState, &auxStateStatus,
4180 &progressPercent, &reasonCode, nullptr);
4181 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4182
4183 rc = decode_get_status_resp(
4184 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4185 &currentState, &previousState, &auxState, &auxStateStatus,
4186 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4187 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4188
4189 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4190 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4192 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304193 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304194 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4195 rc = decode_get_status_resp(
4196 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4197 &currentState, &previousState, &auxState, &auxStateStatus,
4198 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4199 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4200
4201 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4202 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4204 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304205 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304206 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4207 rc = decode_get_status_resp(
4208 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4209 &currentState, &previousState, &auxState, &auxStateStatus,
4210 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4211 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4212
4213 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4214 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4216 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304217 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304218 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4219 rc = decode_get_status_resp(
4220 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4221 &currentState, &previousState, &auxState, &auxStateStatus,
4222 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4223 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4224
4225 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4226 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4228 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304229 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304230 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4231 rc = decode_get_status_resp(
4232 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4233 &currentState, &previousState, &auxState, &auxStateStatus,
4234 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4235 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4236
4237 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4238 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004239 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304240 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304241 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304242 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4243 rc = decode_get_status_resp(
4244 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4245 &currentState, &previousState, &auxState, &auxStateStatus,
4246 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4247 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4248
4249 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4250 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4251 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4252 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304253 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304254 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4255 rc = decode_get_status_resp(
4256 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4257 &currentState, &previousState, &auxState, &auxStateStatus,
4258 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4259 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4260
4261 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4262 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004263 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304264 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304265 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304266 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4267 rc = decode_get_status_resp(
4268 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4269 &currentState, &previousState, &auxState, &auxStateStatus,
4270 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4271 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4272
4273 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4274 // IDLE
4275 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4276 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4278 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304279 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304280 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4281 rc = decode_get_status_resp(
4282 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4283 &currentState, &previousState, &auxState, &auxStateStatus,
4284 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4285 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4286}
4287
4288TEST(CancelUpdateComponent, goodPathEncodeRequest)
4289{
4290 constexpr uint8_t instanceId = 9;
4291 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304292 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304293 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4294
4295 auto rc = encode_cancel_update_component_req(
4296 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4297 EXPECT_EQ(rc, PLDM_SUCCESS);
4298
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004299 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304300 EXPECT_EQ(request, outRequest);
4301}
4302
4303TEST(CancelUpdateComponent, errorPathEncodeRequest)
4304{
4305 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304306 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304307 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4308
4309 auto rc = encode_cancel_update_component_req(
4310 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4311 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4312
4313 rc = encode_cancel_update_component_req(
4314 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4315 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4316}
4317
4318TEST(CancelUpdateComponent, testGoodDecodeResponse)
4319{
4320 uint8_t completionCode = 0;
4321 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4322 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304323 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304324 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4325 cancelUpdateComponentResponse1.data());
4326 auto rc = decode_cancel_update_component_resp(
4327 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4328 &completionCode);
4329 EXPECT_EQ(rc, PLDM_SUCCESS);
4330 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4331
4332 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4333 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304334 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304335 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4336 cancelUpdateComponentResponse2.data());
4337 rc = decode_cancel_update_component_resp(
4338 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4339 &completionCode);
4340 EXPECT_EQ(rc, PLDM_SUCCESS);
4341 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4342}
4343
4344TEST(CancelUpdateComponent, testBadDecodeResponse)
4345{
4346 uint8_t completionCode = 0;
4347 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4348 0x00, 0x00, 0x00};
4349 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304350 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304351 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4352
4353 auto rc = decode_cancel_update_component_resp(
4354 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4355 &completionCode);
4356 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4357
4358 rc = decode_cancel_update_component_resp(
4359 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4360 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4361
4362 rc = decode_cancel_update_component_resp(
4363 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4364 &completionCode);
4365 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4366}
4367
4368TEST(CancelUpdate, goodPathEncodeRequest)
4369{
4370 constexpr uint8_t instanceId = 10;
4371 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304372 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304373 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4374
4375 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4376 PLDM_CANCEL_UPDATE_REQ_BYTES);
4377 EXPECT_EQ(rc, PLDM_SUCCESS);
4378
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004379 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304380 EXPECT_EQ(request, outRequest);
4381}
4382
4383TEST(CancelUpdate, errorPathEncodeRequest)
4384{
4385 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304386 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304387 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4388
4389 auto rc =
4390 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4391 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4392
4393 rc = encode_cancel_update_req(0, requestMsg,
4394 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4395 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4396}
4397
4398TEST(CancelUpdate, goodPathDecodeResponse)
4399{
4400 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4401 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4402 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4404 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304405 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304406 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4407 uint8_t completionCode = 0;
4408 bool8_t nonFunctioningComponentIndication = 0;
4409 bitfield64_t nonFunctioningComponentBitmap{0};
4410 auto rc = decode_cancel_update_resp(
4411 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4412 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4413 EXPECT_EQ(rc, PLDM_SUCCESS);
4414 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4415 EXPECT_EQ(nonFunctioningComponentIndication,
4416 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4417 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4418 nonFunctioningComponentBitmap1);
4419
4420 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4421 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4422 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4424 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304425 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304426 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4427 rc = decode_cancel_update_resp(
4428 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4429 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4430 EXPECT_EQ(rc, PLDM_SUCCESS);
4431 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4432 EXPECT_EQ(nonFunctioningComponentIndication,
4433 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4434 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4435 nonFunctioningComponentBitmap2);
4436
4437 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4438 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4439 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304440 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304441 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4442 rc = decode_cancel_update_resp(
4443 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4444 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4445 EXPECT_EQ(rc, PLDM_SUCCESS);
4446 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4447}
4448
4449TEST(CancelUpdate, errorPathDecodeResponse)
4450{
4451 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4452 0x00};
4453 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304454 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304455 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4456 uint8_t completionCode = 0;
4457 bool8_t nonFunctioningComponentIndication = 0;
4458 bitfield64_t nonFunctioningComponentBitmap{0};
4459
4460 auto rc = decode_cancel_update_resp(
4461 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4462 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4463 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4464
4465 rc = decode_cancel_update_resp(
4466 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4467 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4468 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4469
4470 rc = decode_cancel_update_resp(
4471 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4472 nullptr, &nonFunctioningComponentBitmap);
4473 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4474
4475 rc = decode_cancel_update_resp(
4476 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4477 &nonFunctioningComponentIndication, nullptr);
4478 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4479
4480 rc = decode_cancel_update_resp(
4481 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4482 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4483 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4484
4485 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4486 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4487 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304488 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304489 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4490 rc = decode_cancel_update_resp(
4491 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4492 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4493 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4494
4495 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4496 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4498 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304499 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304500 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4501 rc = decode_cancel_update_resp(
4502 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4503 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4504 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4505}