blob: ebf64956c4366c7dba775ee31a8b5f8e639c758d [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{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930427 // Invalid ComponentImageSetVersionStringType
Andrew Jeffery92c32362025-03-10 03:36:46 +0000428 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
429 0x00, 0x06, 0x0e, 0x00, 0x00};
430 constexpr uint16_t componentBitmapBitLength = 8;
431
432 pldm_firmware_device_id_record deviceIdRecHeader{};
433 variable_field outCompImageSetVersionStr{};
434 variable_field applicableComponents{};
435 variable_field outFwDevicePkgData{};
436 variable_field recordDescriptors{};
437 int rc = 0;
438
439 rc = decode_firmware_device_id_record(
440 nullptr, rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
441 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
442 &outFwDevicePkgData);
443 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
444
445 rc = decode_firmware_device_id_record(
446 rec.data(), rec.size(), componentBitmapBitLength, nullptr,
447 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
448 &outFwDevicePkgData);
449 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
450
451 rc = decode_firmware_device_id_record(
452 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
453 nullptr, &outCompImageSetVersionStr, &recordDescriptors,
454 &outFwDevicePkgData);
455 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
456
457 rc = decode_firmware_device_id_record(
458 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
459 &applicableComponents, nullptr, &recordDescriptors,
460 &outFwDevicePkgData);
461 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
462
463 rc = decode_firmware_device_id_record(
464 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
465 &applicableComponents, &outCompImageSetVersionStr, nullptr,
466 &outFwDevicePkgData);
467 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
468
469 rc = decode_firmware_device_id_record(
470 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
471 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
472 nullptr);
473 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
474
475 rc = decode_firmware_device_id_record(
476 rec.data(), rec.size() - 1, componentBitmapBitLength,
477 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
478 &recordDescriptors, &outFwDevicePkgData);
479 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
480
481 rc = decode_firmware_device_id_record(
482 rec.data(), rec.size(), componentBitmapBitLength + 1,
483 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
484 &recordDescriptors, &outFwDevicePkgData);
485 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
486
487 rc = decode_firmware_device_id_record(
488 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
489 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
490 &outFwDevicePkgData);
491 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
492}
493
494TEST(DecodeFirmwareDeviceIdRecord, invalidComponentImageSetVersionStringLength)
495{
496 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
497 0x00, 0x01, 0x00, 0x00, 0x00};
498 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930499
500 int rc = 0;
501 pldm_firmware_device_id_record deviceIdRecHeader{};
502 variable_field applicableComponents{};
503 variable_field outCompImageSetVersionStr{};
504 variable_field recordDescriptors{};
505 variable_field outFwDevicePkgData{};
506
507 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000508 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
509 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930510 &outFwDevicePkgData);
511 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000512}
513
514TEST(DecodeFirmwareDeviceIdRecord, shortBuffer)
515{
516 constexpr std::array<uint8_t, 11> rec{0x2e, 0x00, 0x01, 0x01, 0x00, 0x00,
517 0x00, 0x01, 0x0e, 0x00, 0x00};
518 constexpr uint16_t componentBitmapBitLength = 8;
519
520 pldm_firmware_device_id_record deviceIdRecHeader{};
521 variable_field outCompImageSetVersionStr{};
522 variable_field applicableComponents{};
523 variable_field outFwDevicePkgData{};
524 variable_field recordDescriptors{};
525 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930526
527 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000528 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
529 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
530 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930531 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000532}
533
534TEST(DecodeFirmwareDeviceIdRecord, recordLengthMismatch)
535{
536 constexpr std::array<uint8_t, 11> rec{0x15, 0x00, 0x01, 0x01, 0x00, 0x00,
537 0x00, 0x01, 0x0e, 0x02, 0x00};
538 constexpr uint16_t componentBitmapBitLength = 8;
539
540 pldm_firmware_device_id_record deviceIdRecHeader{};
541 variable_field outCompImageSetVersionStr{};
542 variable_field applicableComponents{};
543 variable_field outFwDevicePkgData{};
544 variable_field recordDescriptors{};
545 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930546
547 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000548 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
549 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
550 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930551 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000552}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930553
Andrew Jeffery92c32362025-03-10 03:36:46 +0000554TEST(DecodeFirmwareDeviceIdRecord, invalidFirmwareDevicePackageDataLength)
555{
556 constexpr std::array<uint8_t, 49> rec{
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800557 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
558 // FirmwareDevicePackageDataLength = 0xffff
559 0xff, 0xff,
560 //
561 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
562 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
563 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
564 0xab, 0xcd};
Andrew Jeffery92c32362025-03-10 03:36:46 +0000565 constexpr uint16_t componentBitmapBitLength = 8;
566
567 pldm_firmware_device_id_record deviceIdRecHeader{};
568 variable_field outCompImageSetVersionStr{};
569 variable_field applicableComponents{};
570 variable_field outFwDevicePkgData{};
571 variable_field recordDescriptors{};
572 int rc = 0;
573
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800574 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000575 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
576 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
577 &outFwDevicePkgData);
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800578 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930579}
580
581TEST(DecodeDescriptors, goodPath3Descriptors)
582{
583 // In the descriptor data there are 3 descriptor entries
584 // 1) IANA enterprise ID
585 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
586 0x0a, 0x0b, 0x0c, 0xd};
587 // 2) UUID
588 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
589 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
590 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
591 // 3) Vendor Defined
592 constexpr std::string_view vendorTitle{"OpenBMC"};
593 constexpr size_t vendorDescriptorLen = 2;
594 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
595 0x01, 0x02};
596
597 constexpr size_t vendorDefinedDescriptorLen =
598 sizeof(pldm_vendor_defined_descriptor_title_data()
599 .vendor_defined_descriptor_title_str_type) +
600 sizeof(pldm_vendor_defined_descriptor_title_data()
601 .vendor_defined_descriptor_title_str_len) +
602 vendorTitle.size() + vendorDescriptorData.size();
603
604 constexpr size_t descriptorsLength =
605 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
606 sizeof(pldm_descriptor_tlv().descriptor_length)) +
607 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
608
609 constexpr std::array<uint8_t, descriptorsLength> descriptors{
610 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
611 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600612 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930613 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
614
615 size_t descriptorCount = 1;
616 size_t descriptorsRemainingLength = descriptorsLength;
617 int rc = 0;
618
619 while (descriptorsRemainingLength && (descriptorCount <= 3))
620 {
621 uint16_t descriptorType = 0;
622 uint16_t descriptorLen = 0;
623 variable_field descriptorData{};
624
625 rc = decode_descriptor_type_length_value(
626 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
627 descriptorsRemainingLength, &descriptorType, &descriptorData);
628 EXPECT_EQ(rc, PLDM_SUCCESS);
629
630 if (descriptorCount == 1)
631 {
632 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
633 EXPECT_EQ(descriptorData.length,
634 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
635 EXPECT_EQ(true,
636 std::equal(descriptorData.ptr,
637 descriptorData.ptr + descriptorData.length,
638 iana.begin(), iana.end()));
639 }
640 else if (descriptorCount == 2)
641 {
642 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
643 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
644 EXPECT_EQ(true,
645 std::equal(descriptorData.ptr,
646 descriptorData.ptr + descriptorData.length,
647 uuid.begin(), uuid.end()));
648 }
649 else if (descriptorCount == 3)
650 {
651 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
652 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
653
654 uint8_t descriptorTitleStrType = 0;
655 variable_field descriptorTitleStr{};
656 variable_field vendorDefinedDescriptorData{};
657
658 rc = decode_vendor_defined_descriptor_value(
659 descriptorData.ptr, descriptorData.length,
660 &descriptorTitleStrType, &descriptorTitleStr,
661 &vendorDefinedDescriptorData);
662 EXPECT_EQ(rc, PLDM_SUCCESS);
663
664 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
665 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
666 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930667 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930668 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
669 descriptorTitleStr.length);
670 EXPECT_EQ(vendorTitleStr, vendorTitle);
671
672 EXPECT_EQ(vendorDefinedDescriptorData.length,
673 vendorDescriptorData.size());
674 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
675 vendorDefinedDescriptorData.ptr +
676 vendorDefinedDescriptorData.length,
677 vendorDescriptorData.begin(),
678 vendorDescriptorData.end()));
679 }
680
681 descriptorsRemainingLength -= sizeof(descriptorType) +
682 sizeof(descriptorLen) +
683 descriptorData.length;
684 descriptorCount++;
685 }
686}
687
688TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
689{
690 int rc = 0;
691 // IANA Enterprise ID descriptor length incorrect
692 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
693 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
694 uint16_t descriptorType = 0;
695 variable_field descriptorData{};
696
697 rc = decode_descriptor_type_length_value(nullptr,
698 invalidIANADescriptor1.size(),
699 &descriptorType, &descriptorData);
700 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
701
702 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
703 invalidIANADescriptor1.size(),
704 nullptr, &descriptorData);
705 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
706
707 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
708 invalidIANADescriptor1.size(),
709 &descriptorType, nullptr);
710 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
711
712 rc = decode_descriptor_type_length_value(
713 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
714 &descriptorType, &descriptorData);
715 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
716
717 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
718 invalidIANADescriptor1.size(),
719 &descriptorType, &descriptorData);
Andrew Jeffery779e9db2025-02-21 12:14:28 +1030720 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930721
722 // IANA Enterprise ID descriptor data less than length
723 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
724 0x0a, 0x0b, 0x0c};
725 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
726 invalidIANADescriptor2.size(),
727 &descriptorType, &descriptorData);
728 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
729}
730
731TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
732{
733 int rc = 0;
734 // VendorDefinedDescriptorTitleStringType is invalid
735 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
736 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
737 uint8_t descriptorStringType = 0;
738 variable_field descriptorTitleStr{};
739 variable_field vendorDefinedDescriptorData{};
740
741 rc = decode_vendor_defined_descriptor_value(
742 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
743 &descriptorTitleStr, &vendorDefinedDescriptorData);
744 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
745
746 rc = decode_vendor_defined_descriptor_value(
747 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
748 &descriptorStringType, &descriptorTitleStr,
749 &vendorDefinedDescriptorData);
750 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
751
752 rc = decode_vendor_defined_descriptor_value(
753 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
754 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
755 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
756
757 rc = decode_vendor_defined_descriptor_value(
758 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
759 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
760 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
761
762 rc = decode_vendor_defined_descriptor_value(
763 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
764 &descriptorStringType, &descriptorTitleStr, nullptr);
765 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
766
767 rc = decode_vendor_defined_descriptor_value(
768 invalidVendorDescriptor1.data(),
769 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
770 &descriptorStringType, &descriptorTitleStr,
771 &vendorDefinedDescriptorData);
772 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
773
774 rc = decode_vendor_defined_descriptor_value(
775 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
776 &descriptorStringType, &descriptorTitleStr,
777 &vendorDefinedDescriptorData);
778 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
779
780 // VendorDefinedDescriptorTitleStringLength is 0
781 std::array<uint8_t, 9> invalidVendorDescriptor2{
782 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
783 rc = decode_vendor_defined_descriptor_value(
784 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
785 &descriptorStringType, &descriptorTitleStr,
786 &vendorDefinedDescriptorData);
787 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
788
789 // VendorDefinedDescriptorData not present in the data
790 std::array<uint8_t, 9> invalidVendorDescriptor3{
791 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
792 rc = decode_vendor_defined_descriptor_value(
793 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
794 &descriptorStringType, &descriptorTitleStr,
795 &vendorDefinedDescriptorData);
796 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
797}
798
799TEST(DecodeComponentImageInfo, goodPath)
800{
801 // Firmware
802 constexpr uint16_t compClassification = 16;
803 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600804 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930805 // Force update
806 constexpr std::bitset<16> compOptions{1};
807 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
808 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
809 // Random ComponentLocationOffset
810 constexpr uint32_t compLocOffset = 357;
811 // Random ComponentSize
812 constexpr uint32_t compSize = 27;
813 // ComponentVersionString
814 constexpr std::string_view compVersionStr{"VersionString1"};
815 constexpr size_t compImageInfoSize =
816 sizeof(pldm_component_image_information) + compVersionStr.size();
817
818 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
819 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
820 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
821 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
822 pldm_component_image_information outCompImageInfo{};
823 variable_field outCompVersionStr{};
824
825 auto rc =
826 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
827 &outCompImageInfo, &outCompVersionStr);
828
829 EXPECT_EQ(rc, PLDM_SUCCESS);
830 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
831 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
832 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
833 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
834 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
835 reqCompActivationMethod);
836 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
837 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
838 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
839 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
840 compVersionStr.size());
841
842 EXPECT_EQ(outCompVersionStr.length,
843 outCompImageInfo.comp_version_string_length);
844 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930845 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930846 reinterpret_cast<const char*>(outCompVersionStr.ptr),
847 outCompVersionStr.length);
848 EXPECT_EQ(componentVersionString, compVersionStr);
849}
850
851TEST(DecodeComponentImageInfo, errorPaths)
852{
853 int rc = 0;
854 // ComponentVersionString
855 constexpr std::string_view compVersionStr{"VersionString1"};
856 constexpr size_t compImageInfoSize =
857 sizeof(pldm_component_image_information) + compVersionStr.size();
858 // Invalid ComponentVersionStringType - 0x06
859 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
860 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
861 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
862 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
863 pldm_component_image_information outCompImageInfo{};
864 variable_field outCompVersionStr{};
865
866 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
867 &outCompImageInfo, &outCompVersionStr);
868 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
869
870 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
871 invalidCompImageInfo1.size(), nullptr,
872 &outCompVersionStr);
873 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
874
875 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
876 invalidCompImageInfo1.size(),
877 &outCompImageInfo, nullptr);
878 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
879
880 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
881 sizeof(pldm_component_image_information) -
882 1,
883 &outCompImageInfo, &outCompVersionStr);
884 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
885
886 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
887 invalidCompImageInfo1.size(),
888 &outCompImageInfo, &outCompVersionStr);
889 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
890
891 // Invalid ComponentVersionStringLength - 0x00
892 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
893 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
894 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
895 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
896 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
897 invalidCompImageInfo2.size(),
898 &outCompImageInfo, &outCompVersionStr);
899 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
900
901 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600902 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +0930903 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
904 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
905 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
906 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
907
908 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
909 invalidCompImageInfo3.size() - 1,
910 &outCompImageInfo, &outCompVersionStr);
911 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
912
913 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
914 invalidCompImageInfo3.size(),
915 &outCompImageInfo, &outCompVersionStr);
916 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
917
918 // Invalid ComponentLocationOffset - 0
919 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
920 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
921 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
922 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
923 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
924 invalidCompImageInfo4.size(),
925 &outCompImageInfo, &outCompVersionStr);
926 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
927
928 // Invalid ComponentSize - 0
929 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
930 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
931 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
932 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
933 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
934 invalidCompImageInfo5.size(),
935 &outCompImageInfo, &outCompVersionStr);
936 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
937}
938
939TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
940{
941 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930942 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930943 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
944
945 uint8_t instanceId = 0x01;
946
947 auto rc = encode_query_device_identifiers_req(
948 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
949 EXPECT_EQ(rc, PLDM_SUCCESS);
950 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
951 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
952 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
953 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
954}
955
956TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
957{
958 // descriptorDataLen is not fixed here taking it as 6
959 constexpr uint8_t descriptorDataLen = 6;
960 std::array<uint8_t, hdrSize +
961 sizeof(struct pldm_query_device_identifiers_resp) +
962 descriptorDataLen>
963 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930964 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930965 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
966 responseMsg.data() + hdrSize);
967
968 inResp->completion_code = PLDM_SUCCESS;
969 inResp->device_identifiers_len = htole32(descriptorDataLen);
970 inResp->descriptor_count = 1;
971
972 // filling descriptor data
973 std::fill_n(responseMsg.data() + hdrSize +
974 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600975 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930976
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930977 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930978 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
979 uint8_t completionCode = PLDM_SUCCESS;
980 uint32_t deviceIdentifiersLen = 0;
981 uint8_t descriptorCount = 0;
982 uint8_t* outDescriptorData = nullptr;
983
984 auto rc = decode_query_device_identifiers_resp(
985 response, responseMsg.size() - hdrSize, &completionCode,
986 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
987
988 EXPECT_EQ(rc, PLDM_SUCCESS);
989 EXPECT_EQ(completionCode, PLDM_SUCCESS);
990 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
991 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
992 EXPECT_EQ(true,
993 std::equal(outDescriptorData,
994 outDescriptorData + deviceIdentifiersLen,
995 responseMsg.begin() + hdrSize +
996 sizeof(struct pldm_query_device_identifiers_resp),
997 responseMsg.end()));
998}
999
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001000#ifdef LIBPLDM_API_TESTING
1001TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
1002{
1003 int rc;
1004 PLDM_MSG_DEFINE_P(enc, 1000);
1005 size_t enc_payload_len = 1000;
1006 pldm_descriptor check_desc[] = {
1007 {
1008 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
1009 .descriptor_length = 4,
1010 .descriptor_data = "a123",
1011 },
1012 {
1013 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
1014 .descriptor_length = 3,
1015 .descriptor_data = "987",
1016 },
1017 };
1018 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
1019 enc, &enc_payload_len);
1020 EXPECT_EQ(rc, 0);
1021 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
1022 ElementsAreArray<uint8_t>({
1023 // completion code
1024 0x00,
1025 // device identifiers length = 15
1026 0x0f,
1027 0x00,
1028 0x00,
1029 0x00,
1030 // descriptor count
1031 0x02,
1032 // desc 0
1033 0x01,
1034 0x00,
1035 0x04,
1036 0x00,
1037 0x61,
1038 0x31,
1039 0x32,
1040 0x33,
1041 // desc 1
1042 0xff,
1043 0xff,
1044 0x03,
1045 0x00,
1046 0x39,
1047 0x38,
1048 0x37,
1049 }));
1050
1051 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
1052}
1053#endif
1054
Andrew Jeffery9c766792022-08-10 23:12:49 +09301055TEST(GetFirmwareParameters, goodPathEncodeRequest)
1056{
1057 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301058 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301059 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1060 uint8_t instanceId = 0x01;
1061
1062 auto rc = encode_get_firmware_parameters_req(
1063 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
1064 EXPECT_EQ(rc, PLDM_SUCCESS);
1065 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1066 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1067 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1068 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
1069}
1070
1071TEST(GetFirmwareParameters, decodeResponse)
1072{
1073 // CapabilitiesDuringUpdate of the firmware device
1074 // Firmware device downgrade restrictions [Bit position 8] &
1075 // Firmware Device Partial Updates [Bit position 3]
1076 constexpr std::bitset<32> fdCapabilities{0x00000104};
1077 constexpr uint16_t compCount = 1;
1078 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1079 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1080
1081 // constexpr uint16_t compClassification = 16;
1082 // constexpr uint16_t compIdentifier = 300;
1083 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001084 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301085 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
1086 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1087 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
1088 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
1089 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
1090 constexpr std::string_view activeCompVersion{"VersionString3"};
1091 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +09301092
1093 constexpr size_t compParamTableSize =
1094 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
1095 pendingCompVersion.size();
1096
1097 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001098 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301099 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1100 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
1101 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
1102 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1103 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1104
1105 constexpr size_t getFwParamsPayloadLen =
1106 sizeof(pldm_get_firmware_parameters_resp) +
1107 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1108 compParamTableSize;
1109
1110 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1111 getFwParamsResponse{
1112 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1113 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1114 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1115 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001116 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301117 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1118 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1119 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1120 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1121 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1122
1123 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301124 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301125 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1126 pldm_get_firmware_parameters_resp outResp{};
1127 variable_field outActiveCompImageSetVersion{};
1128 variable_field outPendingCompImageSetVersion{};
1129 variable_field outCompParameterTable{};
1130
1131 auto rc = decode_get_firmware_parameters_resp(
1132 responseMsg, getFwParamsPayloadLen, &outResp,
1133 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1134 &outCompParameterTable);
1135
1136 EXPECT_EQ(rc, PLDM_SUCCESS);
1137 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1138 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1139 EXPECT_EQ(outResp.comp_count, compCount);
1140 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1141 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1142 activeCompImageSetVersion.size());
1143 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1144 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1145 pendingCompImageSetVersion.size());
1146 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301147 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301148 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1149 outActiveCompImageSetVersion.length);
1150 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1151 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301152 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301153 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1154 outPendingCompImageSetVersion.length);
1155 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1156 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1157 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1158 outCompParameterTable.ptr +
1159 outCompParameterTable.length,
1160 compParamTable.begin(), compParamTable.end()));
1161}
1162
1163TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1164{
1165 // CapabilitiesDuringUpdate of the firmware device
1166 // FD Host Functionality during Firmware Update [Bit position 2] &
1167 // Component Update Failure Retry Capability [Bit position 1]
1168 constexpr std::bitset<32> fdCapabilities{0x06};
1169 constexpr uint16_t compCount = 0;
1170 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1171 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1172
1173 constexpr size_t getFwParamsPayloadLen =
1174 sizeof(pldm_get_firmware_parameters_resp) +
1175 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1176
1177 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1178 getFwParamsResponse{
1179 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1180 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1181 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1182 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1183
1184 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301185 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301186 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1187 pldm_get_firmware_parameters_resp outResp{};
1188 variable_field outActiveCompImageSetVersion{};
1189 variable_field outPendingCompImageSetVersion{};
1190 variable_field outCompParameterTable{};
1191
1192 auto rc = decode_get_firmware_parameters_resp(
1193 responseMsg, getFwParamsPayloadLen, &outResp,
1194 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1195 &outCompParameterTable);
1196
1197 EXPECT_EQ(rc, PLDM_SUCCESS);
1198 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1199 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1200 EXPECT_EQ(outResp.comp_count, compCount);
1201 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1202 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1203 activeCompImageSetVersion.size());
1204 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1205 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1206 pendingCompImageSetVersion.size());
1207 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301208 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301209 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1210 outActiveCompImageSetVersion.length);
1211 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1212 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301213 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301214 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1215 outPendingCompImageSetVersion.length);
1216 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1217 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1218 EXPECT_EQ(outCompParameterTable.length, 0);
1219}
1220
1221TEST(GetFirmwareParameters,
1222 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1223{
1224 // CapabilitiesDuringUpdate of the firmware device
1225 // FD Host Functionality during Firmware Update [Bit position 2] &
1226 // Component Update Failure Retry Capability [Bit position 1]
1227 constexpr std::bitset<32> fdCapabilities{0x06};
1228 constexpr uint16_t compCount = 0;
1229 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1230
1231 constexpr size_t getFwParamsPayloadLen =
1232 sizeof(pldm_get_firmware_parameters_resp) +
1233 activeCompImageSetVersion.size();
1234
1235 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1236 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1237 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1238 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1239 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1240
1241 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301242 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301243 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1244 pldm_get_firmware_parameters_resp outResp{};
1245 variable_field outActiveCompImageSetVersion{};
1246 variable_field outPendingCompImageSetVersion{};
1247 variable_field outCompParameterTable{};
1248
1249 auto rc = decode_get_firmware_parameters_resp(
1250 responseMsg, getFwParamsPayloadLen, &outResp,
1251 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1252 &outCompParameterTable);
1253
1254 EXPECT_EQ(rc, PLDM_SUCCESS);
1255 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1256 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1257 EXPECT_EQ(outResp.comp_count, compCount);
1258 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1259 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1260 activeCompImageSetVersion.size());
1261 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1262 PLDM_STR_TYPE_UNKNOWN);
1263 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1264 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301265 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301266 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1267 outActiveCompImageSetVersion.length);
1268 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1269 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1270 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1271 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1272 EXPECT_EQ(outCompParameterTable.length, 0);
1273}
1274
1275TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1276{
1277 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1278 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1279
1280 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301281 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301282 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1283 pldm_get_firmware_parameters_resp outResp{};
1284 variable_field outActiveCompImageSetVersion{};
1285 variable_field outPendingCompImageSetVersion{};
1286 variable_field outCompParameterTable{};
1287
1288 auto rc = decode_get_firmware_parameters_resp(
1289 responseMsg, getFwParamsResponse.size(), &outResp,
1290 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1291 &outCompParameterTable);
1292
1293 EXPECT_EQ(rc, PLDM_SUCCESS);
1294 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1295}
1296
1297TEST(GetFirmwareParameters, errorPathdecodeResponse)
1298{
1299 int rc = 0;
1300 // Invalid ActiveComponentImageSetVersionStringType
1301 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1302 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1303 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1304
1305 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301306 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301307 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1308 pldm_get_firmware_parameters_resp outResp{};
1309 variable_field outActiveCompImageSetVersion{};
1310 variable_field outPendingCompImageSetVersion{};
1311 variable_field outCompParameterTable{};
1312
1313 rc = decode_get_firmware_parameters_resp(
1314 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1315 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1316 &outCompParameterTable);
1317 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1318
1319 rc = decode_get_firmware_parameters_resp(
1320 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1321 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1322 &outCompParameterTable);
1323 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1324
1325 rc = decode_get_firmware_parameters_resp(
1326 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1327 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1328 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1329
1330 rc = decode_get_firmware_parameters_resp(
1331 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1332 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1333 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1334
1335 rc = decode_get_firmware_parameters_resp(
1336 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1337 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1338 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1339
1340 rc = decode_get_firmware_parameters_resp(
1341 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1342 &outPendingCompImageSetVersion, &outCompParameterTable);
1343 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1344
1345 rc = decode_get_firmware_parameters_resp(
1346 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1347 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1348 &outCompParameterTable);
1349 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1350
1351 rc = decode_get_firmware_parameters_resp(
1352 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1353 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1354 &outCompParameterTable);
1355 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1356
1357 // Invalid ActiveComponentImageSetVersionStringLength
1358 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1361 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301362 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301363 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1364 rc = decode_get_firmware_parameters_resp(
1365 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1366 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1367 &outCompParameterTable);
1368 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1369
1370 // Invalid PendingComponentImageSetVersionStringType &
1371 // PendingComponentImageSetVersionStringLength
1372 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1373 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1374 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1375 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301376 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301377 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1378 rc = decode_get_firmware_parameters_resp(
1379 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1380 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1381 &outCompParameterTable);
1382 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1383
1384 // Invalid PendingComponentImageSetVersionStringType &
1385 // PendingComponentImageSetVersionStringLength
1386 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1387 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1388 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1389 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301390 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301391 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1392 rc = decode_get_firmware_parameters_resp(
1393 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1394 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1395 &outCompParameterTable);
1396 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1397
1398 // Total payload length less than expected
1399 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1400 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1401 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1402 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301403 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301404 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1405 rc = decode_get_firmware_parameters_resp(
1406 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1407 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1408 &outCompParameterTable);
1409 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1410}
1411
1412TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1413{
1414 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001415 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301416 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001417 constexpr uint16_t compIdentifier = 0x0c0d;
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001418 constexpr uint16_t compClassificationIndex = 0xf;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301419 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001420 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301421 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001422 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301423 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001424 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301425
1426 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1427 constexpr uint8_t activeCompVerStrLen = 8;
1428 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1429 constexpr uint8_t pendingCompVerStrLen = 8;
1430 constexpr size_t entryLength =
1431 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1432 pendingCompVerStrLen;
1433 std::array<uint8_t, entryLength> entry{};
1434
1435 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301436 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301437 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1438
1439 inEntry->comp_classification = htole16(compClassification);
1440 inEntry->comp_identifier = htole16(compIdentifier);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001441 inEntry->comp_classification_index = compClassificationIndex;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301442 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1443 inEntry->active_comp_ver_str_type = 1;
1444 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1445 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001446 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301447 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1448 inEntry->pending_comp_ver_str_type = 1;
1449 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1450 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001451 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301452 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1453 inEntry->capabilities_during_update.value =
1454 htole32(capabilitiesDuringUpdate);
1455 constexpr auto activeCompVerStrPos =
1456 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001457 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301458 constexpr auto pendingCompVerStrPos =
1459 activeCompVerStrPos + activeCompVerStrLen;
1460 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001461 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301462
1463 struct pldm_component_parameter_entry outEntry;
1464 struct variable_field outActiveCompVerStr;
1465 struct variable_field outPendingCompVerStr;
1466
1467 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1468 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1469 &outPendingCompVerStr);
1470
1471 EXPECT_EQ(rc, PLDM_SUCCESS);
1472
1473 EXPECT_EQ(outEntry.comp_classification, compClassification);
1474 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1475 EXPECT_EQ(inEntry->comp_classification_index,
1476 outEntry.comp_classification_index);
1477 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1478 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1479 outEntry.active_comp_ver_str_type);
1480 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1481 outEntry.active_comp_ver_str_len);
1482 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1483 outEntry.active_comp_release_date,
1484 sizeof(inEntry->active_comp_release_date)));
1485 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1486 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1487 outEntry.pending_comp_ver_str_type);
1488 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1489 outEntry.pending_comp_ver_str_len);
1490 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1491 outEntry.pending_comp_release_date,
1492 sizeof(inEntry->pending_comp_release_date)));
1493 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1494 EXPECT_EQ(outEntry.capabilities_during_update.value,
1495 capabilitiesDuringUpdate);
1496
1497 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1498 entry.data() + activeCompVerStrPos,
1499 outActiveCompVerStr.length));
1500 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1501 entry.data() + pendingCompVerStrPos,
1502 outPendingCompVerStr.length));
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001503
1504#ifdef LIBPLDM_API_TESTING
1505 /* Check the roundtrip matches */
1506 std::vector<uint8_t> enc_data(1000);
1507 size_t enc_payload_len = enc_data.size();
1508 struct pldm_component_parameter_entry_full entryFull = {
1509 .comp_classification = compClassification,
1510 .comp_identifier = compIdentifier,
1511 .comp_classification_index = compClassificationIndex,
1512 .active_ver =
1513 {
1514 .comparison_stamp = 0x12345678,
1515 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1516 .str_len = activeCompVerStrLen,
1517 .str_data = {}},
1518 .date = {},
1519 },
1520 .pending_ver =
1521 {
1522 .comparison_stamp = 0x12345678,
1523 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1524 .str_len = pendingCompVerStrLen,
1525 .str_data = {}},
1526 .date = {},
1527 },
1528 .comp_activation_methods = inEntry->comp_activation_methods,
1529 .capabilities_during_update = inEntry->capabilities_during_update,
1530 };
1531 // Fill strings
1532 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1533 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1534 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1535 0xff);
1536 std::fill_n(entryFull.pending_ver.date,
1537 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1538
1539 rc = encode_get_firmware_parameters_resp_comp_entry(
1540 &entryFull, enc_data.data(), &enc_payload_len);
1541 EXPECT_EQ(rc, PLDM_SUCCESS);
1542 EXPECT_EQ(enc_payload_len, entryLength);
1543 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1544#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301545}
1546
Chris Wang4c1f2c72024-03-21 17:09:44 +08001547TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1548{
1549 constexpr uint8_t instanceId = 1;
1550 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301551 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001552 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1553
1554 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1555
Unive Tien71e935c2024-11-25 17:21:43 +08001556 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001557 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1558 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1559 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1560 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1561}
1562
1563TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1564{
1565 constexpr uint8_t instanceId = 1;
1566
1567 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1568
Unive Tien71e935c2024-11-25 17:21:43 +08001569 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001570}
1571
1572TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1573{
1574 uint8_t completion_code_resp = PLDM_SUCCESS;
1575 uint8_t downstream_device_update_supported_resp =
1576 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1577 uint16_t number_of_downstream_devices_resp = 1;
1578 uint16_t max_number_of_downstream_devices_resp = 1;
1579 /** Capabilities of updating downstream devices
1580 * FDP supports downstream devices dynamically attached [Bit position 0] &
1581 * FDP supports downstream devices dynamically removed [Bit position 1]
1582 */
1583 bitfield32_t capabilities_resp = {.value = 0x0002};
1584 int rc;
1585
1586 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1587 responseMsg{};
1588
Andrew Jefferya1896962025-03-03 21:41:25 +10301589 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301590 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1591 responseMsg.size() - hdrSize);
1592 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001593
1594 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1595 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1596 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1597 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1598 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301599 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001600
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301601 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001602 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1603 struct pldm_query_downstream_devices_resp resp_data;
1604
1605 rc = decode_query_downstream_devices_resp(
1606 response, responseMsg.size() - hdrSize, &resp_data);
1607
Unive Tien71e935c2024-11-25 17:21:43 +08001608 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001609 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1610 EXPECT_EQ(resp_data.downstream_device_update_supported,
1611 downstream_device_update_supported_resp);
1612 EXPECT_EQ(resp_data.number_of_downstream_devices,
1613 number_of_downstream_devices_resp);
1614 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1615 max_number_of_downstream_devices_resp);
1616 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1617}
1618
1619TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1620{
1621 uint8_t completion_code_resp = PLDM_SUCCESS;
1622 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1623 uint16_t number_of_downstream_devices_resp = 1;
1624 uint16_t max_number_of_downstream_devices_resp = 1;
1625 /** Capabilities of updating downstream devices
1626 * FDP supports downstream devices dynamically attached [Bit position 0] &
1627 * FDP supports downstream devices dynamically removed [Bit position 1]
1628 */
1629 bitfield32_t capabilities_resp = {.value = 0x0002};
1630 int rc;
1631
1632 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1633 responseMsg{};
1634
Andrew Jefferya1896962025-03-03 21:41:25 +10301635 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301636 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1637 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301638 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001639 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1640 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1641 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1642 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1643 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301644 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001645
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301646 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001647 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1648 struct pldm_query_downstream_devices_resp resp_data;
1649
1650 rc = decode_query_downstream_devices_resp(
1651 response, responseMsg.size() - hdrSize, &resp_data);
1652
Unive Tien71e935c2024-11-25 17:21:43 +08001653 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001654}
1655
1656TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1657{
1658 uint8_t completion_code_resp = PLDM_SUCCESS;
1659 uint8_t downstream_device_update_supported_resp =
1660 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1661 uint16_t number_of_downstream_devices_resp = 1;
1662 uint16_t max_number_of_downstream_devices_resp = 1;
1663 /** Capabilities of updating downstream devices
1664 * FDP supports downstream devices dynamically attached [Bit position 0] &
1665 * FDP supports downstream devices dynamically removed [Bit position 1]
1666 */
1667 bitfield32_t capabilities_resp = {.value = 0x0002};
1668 int rc;
1669
1670 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1671 2 /* Inject error length*/>
1672 responseMsg{};
1673
Andrew Jefferya1896962025-03-03 21:41:25 +10301674 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301675 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1676 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301677 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001678
1679 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1680 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1681 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1682 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1683 // Inject error value
1684 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301685 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001686
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301687 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001688 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1689 struct pldm_query_downstream_devices_resp resp_data;
1690
1691 rc = decode_query_downstream_devices_resp(
1692 response, responseMsg.size() - hdrSize, &resp_data);
1693
Unive Tien71e935c2024-11-25 17:21:43 +08001694 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001695}
1696
Chris Wang458475a2024-03-26 17:59:19 +08001697TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1698{
1699 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301700 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1701 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001702 constexpr pldm_query_downstream_identifiers_req params_req{
1703 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001704
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001705 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1706 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001707 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301708 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1709 ElementsAreArray<uint8_t>(
1710 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001711}
1712
1713TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1714{
1715 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001716 constexpr pldm_query_downstream_identifiers_req params_req{
1717 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1718 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1719 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001720 constexpr size_t payload_length =
1721 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1722 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301723 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001724 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1725
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001726 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1727 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001728 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001729
1730 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001731 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001732 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001733
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001734 rc = encode_query_downstream_identifiers_req(
1735 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001736 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001737}
1738
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301739TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001740{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301741 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1742 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1743 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1744 constexpr uint32_t downstream_devices_length_resp = 0;
1745 constexpr uint16_t number_of_downstream_devices_resp = 0;
1746
1747 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1748 struct pldm_query_downstream_identifiers_resp resp_data = {};
1749 struct pldm_downstream_device_iter devs;
Andrew Jefferya1896962025-03-03 21:41:25 +10301750 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301751 int rc = 0;
1752
1753 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1754 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1755 ASSERT_EQ(rc, 0);
1756
1757 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1758 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1759 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1760 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1761 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1762
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301763 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301764
1765 rc = decode_query_downstream_identifiers_resp(
1766 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1767 &devs);
1768
Unive Tien71e935c2024-11-25 17:21:43 +08001769 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301770 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1771 EXPECT_EQ(resp_data.next_data_transfer_handle,
1772 next_data_transfer_handle_resp);
1773 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1774 EXPECT_EQ(resp_data.downstream_devices_length,
1775 downstream_devices_length_resp);
1776 EXPECT_EQ(resp_data.number_of_downstream_devices,
1777 number_of_downstream_devices_resp);
1778}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301779
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301780TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1781{
1782 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1783 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1784 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1785 constexpr uint32_t downstream_devices_length_resp = 0;
1786 constexpr uint16_t number_of_downstream_devices_resp = 1;
1787
1788 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1789 struct pldm_query_downstream_identifiers_resp resp = {};
1790 struct pldm_downstream_device_iter devs;
1791 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301792 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301793 int rc = 0;
1794
1795 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1796 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1797 ASSERT_EQ(rc, 0);
1798
1799 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1800 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1801 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1802 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1803 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1804
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301805 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301806
1807 rc = decode_query_downstream_identifiers_resp(
1808 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001809 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301810
1811 foreach_pldm_downstream_device(devs, dev, rc)
1812 {
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10301813 FAIL();
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301814 }
1815 ASSERT_NE(rc, 0);
1816}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301817
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301818TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1819{
1820 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301821 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001822 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1823 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1824 const uint32_t downstream_devices_length_resp =
1825 htole32(downstreamDevicesLen);
1826 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301827 constexpr size_t payloadLen =
1828 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001829
Andrew Jefferydec237b2024-11-08 14:33:45 +10301830 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301831 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301832 struct pldm_downstream_device_iter devs;
1833 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301834 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301835 int rc = 0;
1836
1837 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1838 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001839
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301840 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001841 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1842 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1843 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1844 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1845
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301846 /* Downstream device */
1847 pldm_msgbuf_insert_uint16(buf, 1);
1848 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001849
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301850 /* Device descriptor */
1851 pldm_msgbuf_insert_uint16(buf, 1);
1852 pldm_msgbuf_insert_uint16(buf, 4);
1853 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001854
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301855 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301856
1857 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1858 &resp_data, &devs);
1859
Unive Tien71e935c2024-11-25 17:21:43 +08001860 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301861 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001862 EXPECT_EQ(resp_data.next_data_transfer_handle,
1863 next_data_transfer_handle_resp);
1864 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1865 EXPECT_EQ(resp_data.downstream_devices_length,
1866 downstream_devices_length_resp);
1867 EXPECT_EQ(resp_data.number_of_downstream_devices,
1868 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301869
1870 foreach_pldm_downstream_device(devs, dev, rc)
1871 {
1872 struct pldm_descriptor desc;
1873
1874 EXPECT_EQ(dev.downstream_device_index, 1);
1875 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1876
1877 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1878 {
1879 static const uint32_t dmtf = htole32(412);
1880 EXPECT_EQ(desc.descriptor_type, 1);
1881 EXPECT_EQ(desc.descriptor_length, 4);
1882 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1883 }
1884 ASSERT_EQ(rc, 0);
1885 }
1886 ASSERT_EQ(rc, 0);
1887}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301888
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301889constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1890constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1891const uint32_t iana_pen_openbmc = htole16(49871u);
1892const uint32_t iana_pen_dmtf = htole16(412u);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301893
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301894TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1895{
1896 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1897 {0, 1},
1898 {1, 1},
1899 }};
1900
1901 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1902 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1903 &iana_pen_dmtf},
1904 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1905 &iana_pen_openbmc},
1906 }};
1907
1908 constexpr uint32_t downstream_devices_len = 22;
1909 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1910 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1911 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1912 const uint32_t downstream_devices_length_resp =
1913 htole32(downstream_devices_len);
1914 constexpr uint16_t number_of_downstream_devices_resp = 2;
1915 constexpr size_t payloadLen =
1916 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
1917
Patrick Williamsf37edd72024-12-18 11:22:58 -05001918 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301919 PLDM_MSG_DEFINE_P(response, payloadLen);
1920 struct pldm_downstream_device_iter devs;
1921 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301922 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301923 int rc = 0;
1924
1925 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1926 ASSERT_EQ(rc, 0);
1927
1928 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1929 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1930 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1931 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1932 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1933
1934 /* Downstream device */
1935 pldm_msgbuf_insert_uint16(buf, 0);
1936 pldm_msgbuf_insert_uint8(buf, 1);
1937
1938 /* Device descriptor */
1939 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1940 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1941 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
1942
1943 /* Downstream device */
1944 pldm_msgbuf_insert_uint16(buf, 1);
1945 pldm_msgbuf_insert_uint8(buf, 1);
1946
1947 /* Device descriptor */
1948 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
1949 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
1950 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
1951
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301952 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301953
1954 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1955 &resp_data, &devs);
1956
Unive Tien71e935c2024-11-25 17:21:43 +08001957 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301958 EXPECT_EQ(resp_data.number_of_downstream_devices,
1959 number_of_downstream_devices_resp);
1960
1961 size_t devIndex = 0;
1962 size_t descIndex = 0;
1963 foreach_pldm_downstream_device(devs, dev, rc)
1964 {
1965 struct pldm_descriptor desc;
1966
1967 ASSERT_LT(devIndex, expected_devices.size());
1968
1969 const struct pldm_downstream_device* expectedDev =
1970 &expected_devices[devIndex];
1971
1972 EXPECT_EQ(dev.downstream_device_index,
1973 expectedDev->downstream_device_index);
1974 EXPECT_EQ(dev.downstream_descriptor_count,
1975 expectedDev->downstream_descriptor_count);
1976
1977 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1978 {
1979 ASSERT_LT(descIndex, expected_descriptors.size());
1980
1981 const struct pldm_descriptor* expectedDesc =
1982 &expected_descriptors[descIndex];
1983
1984 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
1985 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
1986 EXPECT_EQ(memcmp(desc.descriptor_data,
1987 expectedDesc->descriptor_data,
1988 expectedDesc->descriptor_length),
1989 0);
1990
1991 descIndex++;
1992 }
1993 ASSERT_EQ(rc, 0);
1994 EXPECT_EQ(descIndex, 1 * devIndex + 1);
1995
1996 devIndex++;
1997 }
1998 ASSERT_EQ(rc, 0);
1999 EXPECT_EQ(devIndex, 2);
2000}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302001
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302002TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
2003{
2004 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2005 {0, 2},
2006 {1, 1},
2007 }};
2008
2009 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2010 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2011 &iana_pen_dmtf},
2012 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2013 &iana_pen_openbmc},
2014 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2015 &iana_pen_dmtf},
2016 }};
2017
2018 constexpr uint32_t downstream_devices_len = 30;
2019 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2020 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2021 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2022 const uint32_t downstream_devices_length_resp =
2023 htole32(downstream_devices_len);
2024 constexpr uint16_t number_of_downstream_devices_resp = 2;
2025 constexpr size_t payloadLen =
2026 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2027
Patrick Williamsf37edd72024-12-18 11:22:58 -05002028 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302029 PLDM_MSG_DEFINE_P(response, payloadLen);
2030 struct pldm_downstream_device_iter devs;
2031 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302032 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302033 int rc = 0;
2034
2035 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2036 ASSERT_EQ(rc, 0);
2037
2038 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2039 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2040 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2041 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2042 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2043
2044 /* Downstream device */
2045 pldm_msgbuf_insert_uint16(buf, 0);
2046 pldm_msgbuf_insert_uint8(buf, 2);
2047
2048 /* Device descriptor */
2049 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2050 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2051 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2052
2053 /* Device descriptor */
2054 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2055 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2056 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2057
2058 /* Downstream device */
2059 pldm_msgbuf_insert_uint16(buf, 1);
2060 pldm_msgbuf_insert_uint8(buf, 1);
2061
2062 /* Device descriptor */
2063 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2064 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2065 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2066
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302067 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302068
2069 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2070 &resp_data, &devs);
2071
Unive Tien71e935c2024-11-25 17:21:43 +08002072 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302073 EXPECT_EQ(resp_data.number_of_downstream_devices,
2074 number_of_downstream_devices_resp);
2075
2076 size_t devIndex = 0;
2077 size_t descIndex = 0;
2078 foreach_pldm_downstream_device(devs, dev, rc)
2079 {
2080 struct pldm_descriptor desc;
2081
2082 ASSERT_LT(devIndex, expected_devices.size());
2083
2084 const struct pldm_downstream_device* expectedDev =
2085 &expected_devices[devIndex];
2086
2087 EXPECT_EQ(dev.downstream_device_index,
2088 expectedDev->downstream_device_index);
2089 EXPECT_EQ(dev.downstream_descriptor_count,
2090 expectedDev->downstream_descriptor_count);
2091
2092 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2093 {
2094 ASSERT_LT(descIndex, expected_descriptors.size());
2095
2096 const struct pldm_descriptor* expectedDesc =
2097 &expected_descriptors[descIndex];
2098
2099 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2100 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2101 EXPECT_EQ(memcmp(desc.descriptor_data,
2102 expectedDesc->descriptor_data,
2103 expectedDesc->descriptor_length),
2104 0);
2105
2106 descIndex++;
2107 }
2108 ASSERT_EQ(rc, 0);
2109
2110 devIndex++;
2111 }
2112 ASSERT_EQ(rc, 0);
2113 EXPECT_EQ(devIndex, 2);
2114 EXPECT_EQ(descIndex, 3);
2115}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302116
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302117TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2118{
2119 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2120 {0, 1},
2121 {1, 2},
2122 }};
2123
2124 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2125 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2126 &iana_pen_dmtf},
2127 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2128 &iana_pen_openbmc},
2129 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2130 &iana_pen_dmtf},
2131 }};
2132
2133 constexpr uint32_t downstream_devices_len = 30;
2134 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2135 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2136 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2137 const uint32_t downstream_devices_length_resp =
2138 htole32(downstream_devices_len);
2139 constexpr uint16_t number_of_downstream_devices_resp = 2;
2140 constexpr size_t payloadLen =
2141 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2142
Patrick Williamsf37edd72024-12-18 11:22:58 -05002143 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302144 PLDM_MSG_DEFINE_P(response, payloadLen);
2145 struct pldm_downstream_device_iter devs;
2146 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302147 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302148 int rc = 0;
2149
2150 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2151 ASSERT_EQ(rc, 0);
2152
2153 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2154 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2155 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2156 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2157 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2158
2159 /* Downstream device */
2160 pldm_msgbuf_insert_uint16(buf, 0);
2161 pldm_msgbuf_insert_uint8(buf, 1);
2162
2163 /* Device descriptor */
2164 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2165 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2166 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2167
2168 /* Downstream device */
2169 pldm_msgbuf_insert_uint16(buf, 1);
2170 pldm_msgbuf_insert_uint8(buf, 2);
2171
2172 /* Device descriptor */
2173 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2174 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2175 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2176
2177 /* Device descriptor */
2178 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2179 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2180 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2181
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302182 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302183
2184 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2185 &resp_data, &devs);
2186
Unive Tien71e935c2024-11-25 17:21:43 +08002187 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302188 EXPECT_EQ(resp_data.number_of_downstream_devices,
2189 number_of_downstream_devices_resp);
2190
2191 size_t devIndex = 0;
2192 size_t descIndex = 0;
2193 foreach_pldm_downstream_device(devs, dev, rc)
2194 {
2195 struct pldm_descriptor desc;
2196
2197 ASSERT_LT(devIndex, expected_devices.size());
2198
2199 const struct pldm_downstream_device* expectedDev =
2200 &expected_devices[devIndex];
2201
2202 EXPECT_EQ(dev.downstream_device_index,
2203 expectedDev->downstream_device_index);
2204 EXPECT_EQ(dev.downstream_descriptor_count,
2205 expectedDev->downstream_descriptor_count);
2206
2207 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2208 {
2209 ASSERT_LT(descIndex, expected_descriptors.size());
2210
2211 const struct pldm_descriptor* expectedDesc =
2212 &expected_descriptors[descIndex];
2213
2214 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2215 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2216 EXPECT_EQ(memcmp(desc.descriptor_data,
2217 expectedDesc->descriptor_data,
2218 expectedDesc->descriptor_length),
2219 0);
2220
2221 descIndex++;
2222 }
2223 ASSERT_EQ(rc, 0);
2224
2225 devIndex++;
2226 }
2227 ASSERT_EQ(rc, 0);
2228 EXPECT_EQ(devIndex, 2);
2229 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002230}
2231
2232TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2233{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302234 constexpr size_t payloadLen = sizeof(uint8_t);
2235
Chris Wang458475a2024-03-26 17:59:19 +08002236 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302237 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302238 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002239
2240 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302241 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2242 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002243 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002244
2245 // Test not PLDM_SUCCESS completion code
2246 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302247 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2248 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002249 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002250 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2251
2252 // Test payload length less than minimum length
2253 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302254 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2255 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002256
Unive Tien71e935c2024-11-25 17:21:43 +08002257 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002258}
2259
2260TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2261{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302262 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002263 // 1 descriptor
2264 constexpr uint32_t actualDownstreamDevicesLen = 9;
2265 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2266 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2267 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302268 constexpr uint16_t number_of_downstream_devices_resp = 1;
2269 constexpr size_t payloadLen =
2270 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2271 actualDownstreamDevicesLen;
2272
Chris Wang458475a2024-03-26 17:59:19 +08002273 const uint32_t downstream_devices_length_resp =
2274 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002275
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 void* devicesStart = NULL;
2281 size_t devicesLen;
2282 int rc = 0;
2283
2284 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302285 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002286
2287 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2288 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2289 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2290 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2291 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302292 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002293
Andrew Jefferya1896962025-03-03 21:41:25 +10302294 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2295
Chris Wang458475a2024-03-26 17:59:19 +08002296 /** Filling descriptor data, the correctness of the downstream devices data
2297 * is not checked in this test case so filling with 0xff
2298 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302299 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2300 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002301
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302302 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2303 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002304 0);
Chris Wang458475a2024-03-26 17:59:19 +08002305}
2306
2307TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2308{
2309 constexpr uint32_t actualDownstreamDevicesLen = 0;
2310 constexpr uint16_t number_of_downstream_devices_resp = 1;
2311 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2312 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2313 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302314 constexpr size_t payloadLen =
2315 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2316
Chris Wang458475a2024-03-26 17:59:19 +08002317 const uint32_t downstream_devices_length_resp =
2318 htole32(actualDownstreamDevicesLen);
2319
Andrew Jefferydec237b2024-11-08 14:33:45 +10302320 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302321 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302322 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302323 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302324 int rc = 0;
2325
2326 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2327 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002328
2329 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2330 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2331 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2332 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2333 // Inject error buffer size
2334 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
Andrew Jefferya1896962025-03-03 21:41:25 +10302335 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang458475a2024-03-26 17:59:19 +08002336
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302337 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2338 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002339
Unive Tien71e935c2024-11-25 17:21:43 +08002340 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002341}
2342
Chris Wangb6ef35b2024-07-03 09:35:42 +08002343TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2344{
2345 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302346 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002347 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002348 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302349 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002350 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302351 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002352 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2353
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302354 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002355 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002356 EXPECT_EQ(rc, 0);
2357
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302358 std::array<uint8_t,
2359 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002360 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2361 EXPECT_EQ(requestMsg, expectedReq);
2362}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002363
Chris Wangb6ef35b2024-07-03 09:35:42 +08002364TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2365{
2366 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002367 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302368 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002369 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002370 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302371 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002372 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302373 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002374 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2375
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302376 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002377 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002378 EXPECT_EQ(rc, -EBADMSG);
2379}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002380
Chris Wangb6ef35b2024-07-03 09:35:42 +08002381TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2382{
2383 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002384 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302385 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Andrew Jeffery53b08672025-03-04 12:26:18 +10302386 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002387 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302388 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
Chris Wangb6ef35b2024-07-03 09:35:42 +08002389 1 /* inject erro length*/;
2390
2391 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302392 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002393 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2394
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302395 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002396 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002397 EXPECT_EQ(rc, -EOVERFLOW);
2398}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002399
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302400TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002401{
Chris Wangb6ef35b2024-07-03 09:35:42 +08002402 constexpr uint16_t downstreamDeviceCount = 1;
2403 constexpr uint8_t activeComponentVersionStringLength = 8;
2404 constexpr uint8_t pendingComponentVersionStringLength = 8;
2405 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302406 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002407 activeComponentVersionStringLength +
2408 pendingComponentVersionStringLength;
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302409 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002410 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2411 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2412 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302413 constexpr size_t payload_len =
2414 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2415 downstreamDeviceParamTableLen;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002416
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302417 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302418 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302419 int rc = 0;
2420
2421 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302422 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002423
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302424 // Table 24
2425 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002426 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2427 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302428
2429 // Table 25
Chris Wangb6ef35b2024-07-03 09:35:42 +08002430 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2431 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2432
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302433 // Table 26
2434 pldm_msgbuf_insert_uint16(buf, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002435
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302436 // - Active metadata
2437 pldm_msgbuf_insert_uint32(buf, 0);
2438 pldm_msgbuf_insert_uint8(buf, 1);
2439 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2440 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2441 ASSERT_EQ(rc, 0);
2442
2443 // - Pending metadata
2444 pldm_msgbuf_insert_uint32(buf, 0);
2445 pldm_msgbuf_insert_uint8(buf, 1);
2446 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2447 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2448 ASSERT_EQ(rc, 0);
2449
2450 // - Methods and capabilities
2451 pldm_msgbuf_insert_uint16(buf, 1);
2452 pldm_msgbuf_insert_uint32(buf, 0);
2453
2454 // - Version strings
2455 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2456 "abcdefgh", 8);
2457 ASSERT_EQ(rc, 0);
2458 rc = pldm__msgbuf_insert_array_void(
2459 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2460 ASSERT_EQ(rc, 0);
2461
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302462 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302463 ASSERT_EQ(rc, 0);
2464
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302465 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302466 struct pldm_downstream_device_parameters_iter iter = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002467
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302468 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2469 &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002470
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302471 ASSERT_EQ(rc, 0);
2472 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002473 EXPECT_EQ(resp_data.next_data_transfer_handle,
2474 next_data_transfer_handle_resp);
2475 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2476 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302477
2478 struct pldm_downstream_device_parameters_entry entry;
2479 size_t entries = 0;
2480 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2481 {
2482 EXPECT_EQ(entry.downstream_device_index, 0);
2483 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2484 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2485 EXPECT_EQ(entry.active_comp_ver_str_len,
2486 activeComponentVersionStringLength);
2487 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2488 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2489 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2490 EXPECT_EQ(entry.pending_comp_ver_str_len,
2491 pendingComponentVersionStringLength);
2492 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2493 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2494 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2495 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2496 entry.active_comp_ver_str_len));
2497 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2498 entry.pending_comp_ver_str_len));
2499 entries++;
2500 }
2501 EXPECT_EQ(rc, 0);
2502 EXPECT_EQ(entries, 1);
2503}
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302504
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302505TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2506{
2507 /** Count is not fixed here taking it as 1, and the downstream device's
2508 * version strings length are set to 8
2509 */
2510 constexpr uint16_t downstreamDeviceCount = 2;
2511 constexpr uint8_t activeComponentVersionStringLength = 8;
2512 constexpr uint8_t pendingComponentVersionStringLength = 9;
2513 constexpr size_t downstreamDeviceParamTableLen =
2514 static_cast<size_t>(downstreamDeviceCount *
2515 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2516 activeComponentVersionStringLength +
2517 pendingComponentVersionStringLength));
2518 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2519 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2520 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2521 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2522 constexpr size_t payload_len =
2523 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2524 downstreamDeviceParamTableLen;
2525
2526 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302527 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302528 int rc = 0;
2529
2530 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302531 ASSERT_EQ(rc, 0);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302532
2533 // Table 24
2534 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2535 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2536 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2537
2538 // Table 25
2539 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2540 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2541
2542 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2543 table = {{{
2544 0,
2545 0,
2546 1,
2547 8,
2548 "20241206",
2549 0,
2550 1,
2551 9,
2552 "20241209",
2553 {1},
2554 {0},
2555 "active_0",
2556 "pending_0",
2557 },
2558 {
2559 1,
2560 0,
2561 1,
2562 8,
2563 "20241209",
2564 0,
2565 1,
2566 9,
2567 "20241206",
2568 {1},
2569 {0},
2570 "active_1",
2571 "pending_1",
2572 }}};
2573 for (const auto& e : table)
2574 {
2575 // Table 26
2576 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2577
2578 // - Active metadata
2579 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2580 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2581 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2582 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2583 sizeof(e.active_comp_release_date));
2584 ASSERT_EQ(rc, 0);
2585
2586 // - Pending metadata
2587 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2588 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2589 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2590 rc =
2591 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2592 sizeof(e.pending_comp_release_date));
2593 ASSERT_EQ(rc, 0);
2594
2595 // - Methods and capabilities
2596 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2597 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2598
2599 // - Version strings
2600 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2601 e.active_comp_ver_str,
2602 e.active_comp_ver_str_len);
2603 ASSERT_EQ(rc, 0);
2604 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2605 e.pending_comp_ver_str,
2606 e.pending_comp_ver_str_len);
2607 ASSERT_EQ(rc, 0);
2608 }
2609
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302610 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302611 ASSERT_EQ(rc, 0);
2612
2613 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2614 struct pldm_downstream_device_parameters_iter iter = {};
2615
2616 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2617 &resp_data, &iter);
2618
2619 ASSERT_EQ(rc, 0);
2620 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2621 EXPECT_EQ(resp_data.next_data_transfer_handle,
2622 next_data_transfer_handle_resp);
2623 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2624 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2625
2626 struct pldm_downstream_device_parameters_entry entry;
2627 size_t entryIndex = 0;
2628 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2629 {
2630 ASSERT_LE(entryIndex, table.size());
2631
2632 EXPECT_EQ(table[entryIndex].downstream_device_index,
2633 entry.downstream_device_index);
2634 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2635 entry.active_comp_comparison_stamp);
2636 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2637 entry.active_comp_ver_str_type);
2638 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2639 entry.active_comp_ver_str_len);
2640 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2641 &entry.active_comp_release_date[0]);
2642 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2643 entry.pending_comp_comparison_stamp);
2644 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2645 entry.pending_comp_ver_str_type);
2646 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2647 entry.pending_comp_ver_str_len);
2648 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2649 &entry.pending_comp_release_date[0]);
2650 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2651 entry.comp_activation_methods.value);
2652 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2653 entry.capabilities_during_update.value);
2654 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2655 entry.active_comp_ver_str,
2656 table[entryIndex].active_comp_ver_str_len));
2657 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2658 entry.pending_comp_ver_str,
2659 table[entryIndex].pending_comp_ver_str_len));
2660 entryIndex++;
2661 }
2662 EXPECT_EQ(rc, 0);
2663 EXPECT_EQ(entryIndex, table.size());
Chris Wangb6ef35b2024-07-03 09:35:42 +08002664}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002665
Chris Wangb6ef35b2024-07-03 09:35:42 +08002666TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2667{
2668 /** Count is not fixed here taking it as 1, and the downstream device's
2669 * version strings length are set to 8
2670 */
2671 constexpr uint16_t downstreamDeviceCount = 1;
2672 constexpr uint8_t activeComponentVersionStringLength = 8;
2673 constexpr uint8_t pendingComponentVersionStringLength = 8;
2674 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302675 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002676 activeComponentVersionStringLength +
2677 pendingComponentVersionStringLength;
2678 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2679 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2680 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2681 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2682
2683 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302684 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002685 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2686 responseMsg{};
2687
2688 int rc = 0;
2689
Andrew Jefferya1896962025-03-03 21:41:25 +10302690 PLDM_MSGBUF_DEFINE_P(buf);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002691 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2692 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10302693 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002694
2695 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2696 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2697 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2698 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2699 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
Andrew Jefferya1896962025-03-03 21:41:25 +10302700 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002701
2702 /** Filling paramter table, the correctness of the downstream devices data
2703 * is not checked in this test case so filling with 0xff
2704 */
2705 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302706 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002707 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2708 0xff);
2709
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302710 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002711 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302712 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302713 struct pldm_downstream_device_parameters_iter iter;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002714
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302715 rc = decode_get_downstream_firmware_parameters_resp(
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302716 response, responseMsg.size() - hdrSize, &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002717 EXPECT_EQ(rc, 0);
2718
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302719 struct pldm_downstream_device_parameters_entry entry;
2720 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2721 {
2722 FAIL();
2723 }
2724 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002725}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002726
Andrew Jeffery9c766792022-08-10 23:12:49 +09302727TEST(RequestUpdate, goodPathEncodeRequest)
2728{
2729 constexpr uint8_t instanceId = 1;
2730 constexpr uint32_t maxTransferSize = 512;
2731 constexpr uint16_t numOfComp = 3;
2732 constexpr uint8_t maxOutstandingTransferReq = 2;
2733 constexpr uint16_t pkgDataLen = 0x1234;
2734 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2735 constexpr uint8_t compImgSetVerStrLen =
2736 static_cast<uint8_t>(compImgSetVerStr.size());
2737 variable_field compImgSetVerStrInfo{};
2738 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302739 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302740 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2741 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2742
2743 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2744 compImgSetVerStrLen>
2745 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302746 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302747 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2748
2749 auto rc = encode_request_update_req(
2750 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2751 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2752 &compImgSetVerStrInfo, requestMsg,
2753 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2754 EXPECT_EQ(rc, PLDM_SUCCESS);
2755
2756 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2757 compImgSetVerStrLen>
2758 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2759 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2760 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2761 EXPECT_EQ(request, outRequest);
2762}
2763
2764TEST(RequestUpdate, errorPathEncodeRequest)
2765{
2766 constexpr uint8_t instanceId = 1;
2767 uint32_t maxTransferSize = 512;
2768 constexpr uint16_t numOfComp = 3;
2769 uint8_t maxOutstandingTransferReq = 2;
2770 constexpr uint16_t pkgDataLen = 0x1234;
2771 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2772 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2773 variable_field compImgSetVerStrInfo{};
2774 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302775 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302776 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2777 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2778
2779 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2780 compImgSetVerStr.size()>
2781 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302782 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302783 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2784
2785 auto rc = encode_request_update_req(
2786 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2787 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2788 requestMsg,
2789 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2790 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2791
2792 compImgSetVerStrInfo.ptr = nullptr;
2793 rc = encode_request_update_req(
2794 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2795 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2796 &compImgSetVerStrInfo, requestMsg,
2797 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2798 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2799 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302800 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302801 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2802
2803 rc = encode_request_update_req(
2804 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2805 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2806 &compImgSetVerStrInfo, nullptr,
2807 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2808 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2809
2810 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2811 maxOutstandingTransferReq, pkgDataLen,
2812 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2813 &compImgSetVerStrInfo, requestMsg, 0);
2814 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2815
2816 compImgSetVerStrLen = 0;
2817 rc = encode_request_update_req(
2818 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2819 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2820 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2821 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2822 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2823
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002824 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302825 rc = encode_request_update_req(
2826 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2827 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2828 &compImgSetVerStrInfo, nullptr,
2829 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2830 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2831 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2832
2833 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2834 rc = encode_request_update_req(
2835 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2836 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2837 &compImgSetVerStrInfo, nullptr,
2838 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2839 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2840 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2841
2842 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ - 1;
2843 rc = encode_request_update_req(
2844 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2845 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2846 &compImgSetVerStrInfo, nullptr,
2847 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2848 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2849 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2850
2851 rc = encode_request_update_req(
2852 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2853 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2854 &compImgSetVerStrInfo, nullptr,
2855 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2856 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2857}
2858
2859TEST(RequestUpdate, goodPathDecodeResponse)
2860{
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002861 /* Test a success completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302862 constexpr uint16_t fdMetaDataLen = 1024;
2863 constexpr uint8_t fdWillSendPkgData = 1;
2864 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2865 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2866
2867 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302868 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302869 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2870 uint8_t outCompletionCode = 0;
2871 uint16_t outFdMetaDataLen = 0;
2872 uint8_t outFdWillSendPkgData = 0;
2873
2874 auto rc = decode_request_update_resp(
2875 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2876 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2877 EXPECT_EQ(rc, PLDM_SUCCESS);
2878 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2879 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2880 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2881
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002882#ifdef LIBPLDM_API_TESTING
2883 /* Check the success roundtrip matches */
2884 PLDM_MSG_DEFINE_P(enc, 1000);
2885 size_t enc_payload_len = 1000;
2886 const struct pldm_request_update_resp resp_data = {
2887 .completion_code = PLDM_SUCCESS,
2888 .fd_meta_data_len = outFdMetaDataLen,
2889 .fd_will_send_pkg_data = outFdWillSendPkgData,
2890 };
2891 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2892 &enc_payload_len);
2893 EXPECT_EQ(rc, PLDM_SUCCESS);
2894 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2895 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2896 requestUpdateResponse1.end(), enc_buf + hdrSize));
2897 check_response(enc, PLDM_REQUEST_UPDATE);
2898#endif
2899
2900 /* Test a failure completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302901 outCompletionCode = 0;
2902 outFdMetaDataLen = 0;
2903 outFdWillSendPkgData = 0;
2904
2905 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2906 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2907 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302908 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302909 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2910 rc = decode_request_update_resp(
2911 responseMsg2, requestUpdateResponse2.size() - hdrSize,
2912 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2913 EXPECT_EQ(rc, PLDM_SUCCESS);
2914 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2915}
2916
2917TEST(RequestUpdate, errorPathDecodeResponse)
2918{
2919 constexpr std::array<uint8_t,
2920 hdrSize + sizeof(pldm_request_update_resp) - 1>
2921 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
2922
2923 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302924 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302925 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
2926 uint8_t outCompletionCode = 0;
2927 uint16_t outFdMetaDataLen = 0;
2928 uint8_t outFdWillSendPkgData = 0;
2929
2930 auto rc = decode_request_update_resp(
2931 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2932 &outFdMetaDataLen, &outFdWillSendPkgData);
2933 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2934
2935 rc = decode_request_update_resp(
2936 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
2937 &outFdMetaDataLen, &outFdWillSendPkgData);
2938 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2939
2940 rc = decode_request_update_resp(
2941 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2942 nullptr, &outFdWillSendPkgData);
2943 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2944
2945 rc = decode_request_update_resp(
2946 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2947 &outFdMetaDataLen, nullptr);
2948 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2949
2950 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
2951 &outFdMetaDataLen, &outFdWillSendPkgData);
2952 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2953
2954 rc = decode_request_update_resp(
2955 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
2956 &outFdMetaDataLen, &outFdWillSendPkgData);
2957 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2958}
2959
2960TEST(PassComponentTable, goodPathEncodeRequest)
2961{
2962 constexpr uint8_t instanceId = 1;
2963 constexpr uint16_t compIdentifier = 400;
2964 constexpr uint8_t compClassificationIndex = 40;
2965 constexpr uint32_t compComparisonStamp = 0x12345678;
2966 constexpr std::string_view compVerStr = "0penBmcv1.1";
2967 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
2968 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302969 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302970 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
2971 compVerStrInfo.length = compVerStrLen;
2972
2973 std::array<uint8_t,
2974 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
2975 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302976 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302977 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2978
2979 auto rc = encode_pass_component_table_req(
2980 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
2981 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
2982 compVerStrLen, &compVerStrInfo, requestMsg,
2983 sizeof(pldm_pass_component_table_req) + compVerStrLen);
2984 EXPECT_EQ(rc, PLDM_SUCCESS);
2985
2986 std::array<uint8_t,
2987 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002988 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
2989 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
2990 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09302991 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002992
2993#ifdef LIBPLDM_API_TESTING
2994 /* Check the roundtrip */
2995 struct pldm_pass_component_table_req_full req;
2996 PLDM_MSG_DEFINE_P(dec, outRequest.size());
2997 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
2998 rc =
2999 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
3000 ASSERT_EQ(rc, 0);
3001
3002 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
3003 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3004 EXPECT_EQ(req.comp_identifier, compIdentifier);
3005 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3006 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3007 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3008 EXPECT_EQ(req.version.str_len, compVerStrLen);
3009 EXPECT_TRUE(std::equal(req.version.str_data,
3010 req.version.str_data + req.version.str_len,
3011 compVerStr.data()));
3012#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303013}
3014
3015TEST(PassComponentTable, errorPathEncodeRequest)
3016{
3017 constexpr uint8_t instanceId = 1;
3018 constexpr uint16_t compIdentifier = 400;
3019 constexpr uint8_t compClassificationIndex = 40;
3020 constexpr uint32_t compComparisonStamp = 0x12345678;
3021 constexpr std::string_view compVerStr = "0penBmcv1.1";
3022 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3023 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303024 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303025 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3026 compVerStrInfo.length = compVerStrLen;
3027
3028 std::array<uint8_t,
3029 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3030 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303031 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303032 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3033
3034 auto rc = encode_pass_component_table_req(
3035 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3036 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3037 compVerStrLen, nullptr, requestMsg,
3038 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3039 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3040
3041 compVerStrInfo.ptr = nullptr;
3042 rc = encode_pass_component_table_req(
3043 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3044 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3045 compVerStrLen, &compVerStrInfo, requestMsg,
3046 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3047 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303048 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303049 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3050
3051 rc = encode_pass_component_table_req(
3052 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3053 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3054 compVerStrLen, &compVerStrInfo, nullptr,
3055 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3056 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3057
3058 rc = encode_pass_component_table_req(
3059 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3060 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3061 compVerStrLen, &compVerStrInfo, requestMsg,
3062 sizeof(pldm_pass_component_table_req));
3063 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3064
3065 rc = encode_pass_component_table_req(
3066 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3067 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3068 &compVerStrInfo, requestMsg,
3069 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3070 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3071
3072 rc = encode_pass_component_table_req(
3073 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3074 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3075 compVerStrLen - 1, &compVerStrInfo, requestMsg,
3076 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3077 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3078
3079 rc = encode_pass_component_table_req(
3080 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3081 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3082 compVerStrLen, &compVerStrInfo, requestMsg,
3083 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3084 EXPECT_EQ(rc, PLDM_INVALID_TRANSFER_OPERATION_FLAG);
3085
3086 rc = encode_pass_component_table_req(
3087 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3088 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3089 compVerStrLen, &compVerStrInfo, requestMsg,
3090 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3091 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3092}
3093
3094TEST(PassComponentTable, goodPathDecodeResponse)
3095{
3096 constexpr std::array<uint8_t,
3097 hdrSize + sizeof(pldm_pass_component_table_resp)>
3098 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3099 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303100 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303101 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3102
3103 uint8_t completionCode = 0;
3104 uint8_t compResp = 0;
3105 uint8_t compRespCode = 0;
3106
3107 auto rc = decode_pass_component_table_resp(
3108 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3109 &compResp, &compRespCode);
3110
3111 EXPECT_EQ(rc, PLDM_SUCCESS);
3112 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3113 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3114 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3115
3116 constexpr std::array<uint8_t,
3117 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003118 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303119 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303120 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303121 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3122 rc = decode_pass_component_table_resp(
3123 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3124 &compResp, &compRespCode);
3125
3126 EXPECT_EQ(rc, PLDM_SUCCESS);
3127 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3128 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3129 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3130
3131 constexpr std::array<uint8_t,
3132 hdrSize + sizeof(pldm_pass_component_table_resp)>
3133 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3134 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303135 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303136 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3137
3138 rc = decode_pass_component_table_resp(
3139 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3140 &compResp, &compRespCode);
3141
3142 EXPECT_EQ(rc, PLDM_SUCCESS);
3143 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3144}
3145
3146TEST(PassComponentTable, errorPathDecodeResponse)
3147{
3148 constexpr std::array<uint8_t,
3149 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3150 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3151 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303152 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303153 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3154
3155 uint8_t completionCode = 0;
3156 uint8_t compResp = 0;
3157 uint8_t compRespCode = 0;
3158
3159 auto rc = decode_pass_component_table_resp(
3160 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3161 &compResp, &compRespCode);
3162 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3163
3164 rc = decode_pass_component_table_resp(
3165 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3166 &compResp, &compRespCode);
3167 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3168
3169 rc = decode_pass_component_table_resp(
3170 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3171 &completionCode, nullptr, &compRespCode);
3172 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3173
3174 rc = decode_pass_component_table_resp(
3175 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3176 &completionCode, &compResp, nullptr);
3177 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3178
3179 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3180 &compResp, &compRespCode);
3181 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3182
3183 rc = decode_pass_component_table_resp(
3184 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3185 &completionCode, &compResp, &compRespCode);
3186 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3187
3188 constexpr std::array<uint8_t,
3189 hdrSize + sizeof(pldm_pass_component_table_resp)>
3190 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3191 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303192 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303193 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3194 rc = decode_pass_component_table_resp(
3195 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3196 &compResp, &compRespCode);
3197 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3198
3199 constexpr std::array<uint8_t,
3200 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003201 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303202 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303203 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303204 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3205 rc = decode_pass_component_table_resp(
3206 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3207 &compResp, &compRespCode);
3208 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3209
3210 constexpr std::array<uint8_t,
3211 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003212 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303213 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303214 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303215 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3216 rc = decode_pass_component_table_resp(
3217 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3218 &compResp, &compRespCode);
3219 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3220}
3221
3222TEST(UpdateComponent, goodPathEncodeRequest)
3223{
3224 constexpr uint8_t instanceId = 2;
3225 constexpr uint16_t compIdentifier = 500;
3226 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003227 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303228 constexpr uint32_t compImageSize = 4096;
3229 constexpr bitfield32_t updateOptionFlags{1};
3230 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3231 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3232 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303233 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303234 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3235 compVerStrInfo.length = compVerStrLen;
3236
3237 std::array<uint8_t,
3238 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3239 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303240 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303241 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3242
3243 auto rc = encode_update_component_req(
3244 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3245 compComparisonStamp, compImageSize, updateOptionFlags,
3246 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3247 sizeof(pldm_update_component_req) + compVerStrLen);
3248 EXPECT_EQ(rc, PLDM_SUCCESS);
3249
3250 std::array<uint8_t,
3251 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003252 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3253 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3254 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3255 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303256 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003257
3258#ifdef LIBPLDM_API_TESTING
3259 /* Check the roundtrip */
3260 struct pldm_update_component_req_full req;
3261 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3262 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3263 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3264 ASSERT_EQ(rc, 0);
3265
3266 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3267 EXPECT_EQ(req.comp_identifier, compIdentifier);
3268 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3269 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3270 EXPECT_EQ(req.comp_image_size, compImageSize);
3271 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3272 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3273 EXPECT_EQ(req.version.str_len, compVerStrLen);
3274 EXPECT_TRUE(std::equal(req.version.str_data,
3275 req.version.str_data + req.version.str_len,
3276 compVerStr.data()));
3277#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303278}
3279
3280TEST(UpdateComponent, errorPathEncodeRequest)
3281{
3282 constexpr uint8_t instanceId = 2;
3283 constexpr uint16_t compIdentifier = 500;
3284 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003285 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303286 constexpr uint32_t compImageSize = 4096;
3287 constexpr bitfield32_t updateOptionFlags{1};
3288 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3289 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3290 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303291 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303292 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3293 compVerStrInfo.length = compVerStrLen;
3294
3295 std::array<uint8_t,
3296 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3297 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303298 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303299 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3300
3301 auto rc = encode_update_component_req(
3302 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3303 compComparisonStamp, compImageSize, updateOptionFlags,
3304 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3305 sizeof(pldm_update_component_req) + compVerStrLen);
3306 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3307
3308 compVerStrInfo.ptr = nullptr;
3309 rc = encode_update_component_req(
3310 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3311 compComparisonStamp, compImageSize, updateOptionFlags,
3312 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3313 sizeof(pldm_update_component_req) + compVerStrLen);
3314 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303315 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303316 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3317
3318 rc = encode_update_component_req(
3319 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3320 compComparisonStamp, compImageSize, updateOptionFlags,
3321 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3322 sizeof(pldm_update_component_req) + compVerStrLen);
3323 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3324
3325 rc = encode_update_component_req(
3326 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3327 compComparisonStamp, compImageSize, updateOptionFlags,
3328 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3329 sizeof(pldm_update_component_req));
3330 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3331
3332 rc = encode_update_component_req(
3333 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3334 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3335 compVerStrLen, &compVerStrInfo, requestMsg,
3336 sizeof(pldm_update_component_req) + compVerStrLen);
3337 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3338
3339 rc = encode_update_component_req(
3340 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3341 compComparisonStamp, compImageSize, updateOptionFlags,
3342 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3343 sizeof(pldm_update_component_req) + compVerStrLen);
3344 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3345
3346 rc = encode_update_component_req(
3347 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3348 compComparisonStamp, compImageSize, updateOptionFlags,
3349 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3350 sizeof(pldm_update_component_req) + compVerStrLen);
3351 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3352
3353 rc = encode_update_component_req(
3354 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3355 compComparisonStamp, compImageSize, updateOptionFlags,
3356 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3357 sizeof(pldm_update_component_req) + compVerStrLen);
3358 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3359}
3360
3361TEST(UpdateComponent, goodPathDecodeResponse)
3362{
3363 constexpr std::bitset<32> forceUpdateComp{1};
3364 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3365 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3366 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3367 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3368 auto responseMsg1 =
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*>(updateComponentResponse1.data());
3371
3372 uint8_t completionCode = 0;
3373 uint8_t compCompatibilityResp = 0;
3374 uint8_t compCompatibilityRespCode = 0;
3375 bitfield32_t updateOptionFlagsEnabled{};
3376 uint16_t timeBeforeReqFWData = 0;
3377
3378 auto rc = decode_update_component_resp(
3379 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3380 &compCompatibilityResp, &compCompatibilityRespCode,
3381 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3382
3383 EXPECT_EQ(rc, PLDM_SUCCESS);
3384 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3385 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3386 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3387 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3388 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3389
3390 constexpr std::bitset<32> noFlags{};
3391 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3392 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3393 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3395 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303396 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303397 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3398 rc = decode_update_component_resp(
3399 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3400 &compCompatibilityResp, &compCompatibilityRespCode,
3401 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3402
3403 EXPECT_EQ(rc, PLDM_SUCCESS);
3404 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3405 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3406 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3407 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3408 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3409
3410 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3411 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3412 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303413 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303414 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3415
3416 rc = decode_update_component_resp(
3417 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3418 &compCompatibilityResp, &compCompatibilityRespCode,
3419 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3420
3421 EXPECT_EQ(rc, PLDM_SUCCESS);
3422 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3423}
3424
3425TEST(UpdateComponent, errorPathDecodeResponse)
3426{
3427 constexpr std::array<uint8_t,
3428 hdrSize + sizeof(pldm_update_component_resp) - 1>
3429 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3430 0x00, 0x00, 0x00, 0x00, 0x00};
3431 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303432 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303433 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3434
3435 uint8_t completionCode = 0;
3436 uint8_t compCompatibilityResp = 0;
3437 uint8_t compCompatibilityRespCode = 0;
3438 bitfield32_t updateOptionFlagsEnabled{};
3439 uint16_t timeBeforeReqFWData = 0;
3440
3441 auto rc = decode_update_component_resp(
3442 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3443 &compCompatibilityResp, &compCompatibilityRespCode,
3444 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3445 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3446
3447 rc = decode_update_component_resp(
3448 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3449 &compCompatibilityResp, &compCompatibilityRespCode,
3450 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3451 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3452
3453 rc = decode_update_component_resp(
3454 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3455 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3456 &timeBeforeReqFWData);
3457 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3458
3459 rc = decode_update_component_resp(
3460 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3461 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3462 &timeBeforeReqFWData);
3463 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3464
3465 rc = decode_update_component_resp(
3466 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3467 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3468 &timeBeforeReqFWData);
3469 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3470
3471 rc = decode_update_component_resp(
3472 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3473 &compCompatibilityResp, &compCompatibilityRespCode,
3474 &updateOptionFlagsEnabled, nullptr);
3475 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3476
3477 rc = decode_update_component_resp(
3478 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3479 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3480 &timeBeforeReqFWData);
3481 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3482
3483 rc = decode_update_component_resp(
3484 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3485 &compCompatibilityResp, &compCompatibilityRespCode,
3486 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3487 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3488
3489 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3490 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3491 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3492 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303493 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303494 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3495 rc = decode_update_component_resp(
3496 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3497 &compCompatibilityResp, &compCompatibilityRespCode,
3498 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3499 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3500
3501 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003502 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303503 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3504 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303505 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303506 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3507 rc = decode_update_component_resp(
3508 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3509 &compCompatibilityResp, &compCompatibilityRespCode,
3510 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3511 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3512
3513 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003514 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303515 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3516 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303517 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303518 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3519 rc = decode_update_component_resp(
3520 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3521 &compCompatibilityResp, &compCompatibilityRespCode,
3522 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3523 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3524}
3525
3526TEST(RequestFirmwareData, goodPathDecodeRequest)
3527{
3528 constexpr uint32_t offset = 300;
3529 constexpr uint32_t length = 255;
3530 constexpr std::array<uint8_t,
3531 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003532 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3533 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303534 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303535 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3536
3537 uint32_t outOffset = 0;
3538 uint32_t outLength = 0;
3539 auto rc = decode_request_firmware_data_req(
3540 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3541 &outLength);
3542
3543 EXPECT_EQ(rc, PLDM_SUCCESS);
3544 EXPECT_EQ(outOffset, offset);
3545 EXPECT_EQ(outLength, length);
3546}
3547
3548TEST(RequestFirmwareData, errorPathDecodeRequest)
3549{
3550 constexpr std::array<uint8_t,
3551 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003552 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3553 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303554 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303555 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3556
3557 uint32_t outOffset = 0;
3558 uint32_t outLength = 0;
3559 auto rc = decode_request_firmware_data_req(
3560 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3561 &outLength);
3562 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3563
3564 rc = decode_request_firmware_data_req(
3565 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3566 &outLength);
3567 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3568
3569 rc = decode_request_firmware_data_req(
3570 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3571 nullptr);
3572 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3573
3574 rc = decode_request_firmware_data_req(
3575 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3576 &outLength);
3577 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3578
3579 rc = decode_request_firmware_data_req(
3580 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3581 &outLength);
3582 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3583}
3584
3585TEST(RequestFirmwareData, goodPathEncodeResponse)
3586{
3587 constexpr uint8_t instanceId = 3;
3588 constexpr uint8_t completionCode = PLDM_SUCCESS;
3589 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3590 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3591 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003592 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3593 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3594 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3595 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303596 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3597 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3598 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003599 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3600 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3601 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3602 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303603 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303604 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3605 auto rc = encode_request_firmware_data_resp(
3606 instanceId, completionCode, responseMsg1,
3607 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3608 EXPECT_EQ(rc, PLDM_SUCCESS);
3609 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3610
3611 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3612 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3613 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3614 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303615 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303616 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3617 rc = encode_request_firmware_data_resp(
3618 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3619 sizeof(completionCode));
3620 EXPECT_EQ(rc, PLDM_SUCCESS);
3621 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3622}
3623
3624TEST(RequestFirmwareData, errorPathEncodeResponse)
3625{
3626 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303627 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303628 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3629 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3630 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3631
3632 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3633 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3634}
3635
3636TEST(TransferComplete, goodPathDecodeRequest)
3637{
3638 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3639 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3640 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3641 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303642 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303643 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3644 uint8_t outTransferResult = 0;
3645
3646 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3647 &outTransferResult);
3648 EXPECT_EQ(rc, PLDM_SUCCESS);
3649 EXPECT_EQ(outTransferResult, transferResult);
3650
3651 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3652 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3653 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303654 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303655 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3656 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3657 &outTransferResult);
3658 EXPECT_EQ(rc, PLDM_SUCCESS);
3659 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3660}
3661
3662TEST(TransferComplete, errorPathDecodeRequest)
3663{
3664 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3665 0x00};
3666 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303667 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303668 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3669 uint8_t outTransferResult = 0;
3670
3671 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3672 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3673
3674 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3675 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3676
3677 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3678 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3679}
3680
3681TEST(TransferComplete, goodPathEncodeResponse)
3682{
3683 constexpr uint8_t instanceId = 4;
3684 constexpr uint8_t completionCode = PLDM_SUCCESS;
3685 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3686 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3687 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3688 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3689 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303690 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303691 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3692 auto rc = encode_transfer_complete_resp(
3693 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3694 EXPECT_EQ(rc, PLDM_SUCCESS);
3695 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3696
3697 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3698 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3699 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3700 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3701 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303702 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303703 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3704 rc = encode_transfer_complete_resp(instanceId,
3705 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3706 responseMsg2, sizeof(completionCode));
3707 EXPECT_EQ(rc, PLDM_SUCCESS);
3708 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3709}
3710
3711TEST(TransferComplete, errorPathEncodeResponse)
3712{
3713 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3714 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303715 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303716 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3717 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3718 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3719
3720 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3721 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3722}
3723
3724TEST(VerifyComplete, goodPathDecodeRequest)
3725{
3726 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3727 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3728 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3729 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303730 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303731 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3732 uint8_t outVerifyResult = 0;
3733
3734 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3735 &outVerifyResult);
3736 EXPECT_EQ(rc, PLDM_SUCCESS);
3737 EXPECT_EQ(outVerifyResult, verifyResult);
3738
3739 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3740 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3741 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303742 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303743 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3744 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3745 &outVerifyResult);
3746 EXPECT_EQ(rc, PLDM_SUCCESS);
3747 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3748}
3749
3750TEST(VerifyComplete, errorPathDecodeRequest)
3751{
3752 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3753 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303754 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303755 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3756 uint8_t outVerifyResult = 0;
3757
3758 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3759 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3760
3761 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3762 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3763
3764 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3765 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3766}
3767
3768TEST(VerifyComplete, goodPathEncodeResponse)
3769{
3770 constexpr uint8_t instanceId = 5;
3771 constexpr uint8_t completionCode = PLDM_SUCCESS;
3772 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3773 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3774 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3775 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3776 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303777 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303778 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3779 auto rc = encode_verify_complete_resp(instanceId, completionCode,
3780 responseMsg1, sizeof(completionCode));
3781 EXPECT_EQ(rc, PLDM_SUCCESS);
3782 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3783
3784 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3785 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3786 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3787 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3788 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303789 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303790 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3791 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3792 responseMsg2, sizeof(completionCode));
3793 EXPECT_EQ(rc, PLDM_SUCCESS);
3794 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3795}
3796
3797TEST(VerifyComplete, errorPathEncodeResponse)
3798{
3799 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3800 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303801 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303802 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3803 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3804 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3805
3806 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3807 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3808}
3809
3810TEST(ApplyComplete, goodPathDecodeRequest)
3811{
3812 constexpr uint8_t applyResult1 =
3813 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3814 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3815 constexpr std::bitset<16> compActivationModification1{0x30};
3816 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3817 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3818 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303819 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303820 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3821 uint8_t outApplyResult = 0;
3822 bitfield16_t outCompActivationModification{};
3823 auto rc = decode_apply_complete_req(
3824 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3825 &outCompActivationModification);
3826 EXPECT_EQ(rc, PLDM_SUCCESS);
3827 EXPECT_EQ(outApplyResult, applyResult1);
3828 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
3829
3830 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
3831 constexpr std::bitset<16> compActivationModification2{};
3832 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3833 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3834 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303835 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303836 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3837 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3838 &outApplyResult,
3839 &outCompActivationModification);
3840 EXPECT_EQ(rc, PLDM_SUCCESS);
3841 EXPECT_EQ(outApplyResult, applyResult2);
3842 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
3843}
3844
3845TEST(ApplyComplete, errorPathDecodeRequest)
3846{
3847 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
3848 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303849 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303850 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3851 uint8_t outApplyResult = 0;
3852 bitfield16_t outCompActivationModification{};
3853
3854 auto rc = decode_apply_complete_req(
3855 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
3856 &outCompActivationModification);
3857 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3858
3859 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3860 nullptr, &outCompActivationModification);
3861 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3862
3863 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
3864 &outApplyResult, nullptr);
3865 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3866
3867 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
3868 &outCompActivationModification);
3869 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3870
3871 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3872 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
3873 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303874 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303875 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
3876 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
3877 &outApplyResult,
3878 &outCompActivationModification);
3879 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3880}
3881
3882TEST(ApplyComplete, goodPathEncodeResponse)
3883{
3884 constexpr uint8_t instanceId = 6;
3885 constexpr uint8_t completionCode = PLDM_SUCCESS;
3886 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3887 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
3888 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3889 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3890 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303891 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303892 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
3893 auto rc = encode_apply_complete_resp(instanceId, completionCode,
3894 responseMsg1, sizeof(completionCode));
3895 EXPECT_EQ(rc, PLDM_SUCCESS);
3896 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
3897
3898 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3899 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
3900 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3901 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3902 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303903 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303904 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
3905 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3906 responseMsg2, sizeof(completionCode));
3907 EXPECT_EQ(rc, PLDM_SUCCESS);
3908 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
3909}
3910
3911TEST(ApplyComplete, errorPathEncodeResponse)
3912{
3913 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
3914 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303915 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303916 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
3917 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3918 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3919
3920 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3921 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3922}
3923
3924TEST(ActivateFirmware, goodPathEncodeRequest)
3925{
3926 constexpr uint8_t instanceId = 7;
3927
3928 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303929 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303930 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3931
3932 auto rc = encode_activate_firmware_req(
3933 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
3934 sizeof(pldm_activate_firmware_req));
3935 EXPECT_EQ(rc, PLDM_SUCCESS);
3936
3937 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003938 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303939 EXPECT_EQ(request, outRequest);
3940}
3941
3942TEST(ActivateFirmware, errorPathEncodeRequest)
3943{
3944 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303945 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303946 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3947
3948 auto rc = encode_activate_firmware_req(
3949 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
3950 sizeof(pldm_activate_firmware_req));
3951 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3952
3953 rc = encode_activate_firmware_req(
3954 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
3955 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3956
3957 rc = encode_activate_firmware_req(0, 2, requestMsg,
3958 sizeof(pldm_activate_firmware_req));
3959 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3960}
3961
3962TEST(ActivateFirmware, goodPathDecodeResponse)
3963{
3964 constexpr uint16_t estimatedTimeForActivation100s = 100;
3965 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3966 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
3967 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303968 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303969 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
3970
3971 uint8_t completionCode = 0;
3972 uint16_t estimatedTimeForActivation = 0;
3973
3974 auto rc = decode_activate_firmware_resp(
3975 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
3976 &estimatedTimeForActivation);
3977
3978 EXPECT_EQ(rc, PLDM_SUCCESS);
3979 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3980 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
3981
3982 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3983 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
3984 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303985 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303986 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
3987
3988 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
3989 &completionCode,
3990 &estimatedTimeForActivation);
3991
3992 EXPECT_EQ(rc, PLDM_SUCCESS);
3993 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
3994}
3995
3996TEST(ActivateFirmware, errorPathDecodeResponse)
3997{
3998 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
3999 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4000 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304001 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304002 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
4003
4004 uint8_t completionCode = 0;
4005 uint16_t estimatedTimeForActivation = 0;
4006
4007 auto rc = decode_activate_firmware_resp(
4008 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
4009 &estimatedTimeForActivation);
4010 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4011
4012 rc = decode_activate_firmware_resp(responseMsg,
4013 sizeof(pldm_activate_firmware_resp),
4014 nullptr, &estimatedTimeForActivation);
4015 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4016
4017 rc = decode_activate_firmware_resp(responseMsg,
4018 sizeof(pldm_activate_firmware_resp),
4019 &completionCode, nullptr);
4020 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4021
4022 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
4023 &estimatedTimeForActivation);
4024 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4025
4026 rc = decode_activate_firmware_resp(
4027 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
4028 &estimatedTimeForActivation);
4029 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4030}
4031
4032TEST(GetStatus, goodPathEncodeRequest)
4033{
4034 constexpr uint8_t instanceId = 8;
4035 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304036 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304037 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4038
4039 auto rc = encode_get_status_req(instanceId, requestMsg,
4040 PLDM_GET_STATUS_REQ_BYTES);
4041 EXPECT_EQ(rc, PLDM_SUCCESS);
4042
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004043 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304044 EXPECT_EQ(request, outRequest);
4045}
4046
4047TEST(GetStatus, errorPathEncodeRequest)
4048{
4049 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304050 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304051 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4052
4053 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4054 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4055
4056 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4057 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4058}
4059
4060TEST(GetStatus, goodPathDecodeResponse)
4061{
4062 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4063 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4064 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4065 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4066 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304067 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304068 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4069
4070 uint8_t completionCode = 0;
4071 uint8_t currentState = 0;
4072 uint8_t previousState = 0;
4073 uint8_t auxState = 0;
4074 uint8_t auxStateStatus = 0;
4075 uint8_t progressPercent = 0;
4076 uint8_t reasonCode = 0;
4077 bitfield32_t updateOptionFlagsEnabled{0};
4078
4079 auto rc = decode_get_status_resp(
4080 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4081 &currentState, &previousState, &auxState, &auxStateStatus,
4082 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4083
4084 EXPECT_EQ(rc, PLDM_SUCCESS);
4085 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4086 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4087 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4088 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4089 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4090 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4091 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4092 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4093
4094 // Bit position 0 - Force update of component – FD will perform a force
4095 // update of the component.
4096 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4097 constexpr uint8_t progressPercent2 = 50;
4098 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4099 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4100 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4101 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304102 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304103 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4104
4105 rc = decode_get_status_resp(
4106 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4107 &currentState, &previousState, &auxState, &auxStateStatus,
4108 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4109
4110 EXPECT_EQ(rc, PLDM_SUCCESS);
4111 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4112 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4113 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4114 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4115 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4116 EXPECT_EQ(progressPercent, progressPercent2);
4117 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4118 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4119
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004120#ifdef LIBPLDM_API_TESTING
4121 /* Check the roundtrip */
4122 PLDM_MSG_DEFINE_P(enc, 1000);
4123 size_t enc_payload_len = 1000;
4124 const struct pldm_get_status_resp status_enc = {
4125 .completion_code = PLDM_SUCCESS,
4126 .current_state = currentState,
4127 .previous_state = previousState,
4128 .aux_state = auxState,
4129 .aux_state_status = auxStateStatus,
4130 .progress_percent = progressPercent,
4131 .reason_code = reasonCode,
4132 .update_option_flags_enabled = updateOptionFlagsEnabled,
4133 };
4134 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4135 &enc_payload_len);
4136 EXPECT_EQ(rc, PLDM_SUCCESS);
4137 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4138 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4139 getStatusResponse2.end(), enc_buf + hdrSize));
4140 check_response(enc, PLDM_GET_STATUS);
4141#endif
4142
4143 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304144 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4145 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4146 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304147 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304148 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4149 rc = decode_get_status_resp(
4150 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4151 &currentState, &previousState, &auxState, &auxStateStatus,
4152 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4153 EXPECT_EQ(rc, PLDM_SUCCESS);
4154 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4155}
4156
4157TEST(GetStatus, errorPathDecodeResponse)
4158{
4159 uint8_t completionCode = 0;
4160 uint8_t currentState = 0;
4161 uint8_t previousState = 0;
4162 uint8_t auxState = 0;
4163 uint8_t auxStateStatus = 0;
4164 uint8_t progressPercent = 0;
4165 uint8_t reasonCode = 0;
4166 bitfield32_t updateOptionFlagsEnabled{0};
4167
4168 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4169 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304170 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304171 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4172
4173 auto rc = decode_get_status_resp(
4174 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4175 &currentState, &previousState, &auxState, &auxStateStatus,
4176 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4177 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4178
4179 rc = decode_get_status_resp(
4180 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4181 &currentState, &previousState, &auxState, &auxStateStatus,
4182 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4183 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4184
4185 rc = decode_get_status_resp(
4186 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4187 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4188 &reasonCode, &updateOptionFlagsEnabled);
4189 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4190
4191 rc = decode_get_status_resp(
4192 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4193 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4194 &reasonCode, &updateOptionFlagsEnabled);
4195 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4196
4197 rc = decode_get_status_resp(
4198 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4199 &currentState, &previousState, nullptr, &auxStateStatus,
4200 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4201 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4202
4203 rc = decode_get_status_resp(
4204 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4205 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4206 &reasonCode, &updateOptionFlagsEnabled);
4207 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4208
4209 rc = decode_get_status_resp(
4210 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4211 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4212 &reasonCode, &updateOptionFlagsEnabled);
4213 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4214
4215 rc = decode_get_status_resp(
4216 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4217 &currentState, &previousState, &auxState, &auxStateStatus,
4218 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4219 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4220
4221 rc = decode_get_status_resp(
4222 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4223 &currentState, &previousState, &auxState, &auxStateStatus,
4224 &progressPercent, &reasonCode, nullptr);
4225 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4226
4227 rc = decode_get_status_resp(
4228 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4229 &currentState, &previousState, &auxState, &auxStateStatus,
4230 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4231 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4232
4233 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4234 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4236 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304237 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304238 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4239 rc = decode_get_status_resp(
4240 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4241 &currentState, &previousState, &auxState, &auxStateStatus,
4242 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4243 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4244
4245 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4246 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4248 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304249 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304250 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4251 rc = decode_get_status_resp(
4252 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4253 &currentState, &previousState, &auxState, &auxStateStatus,
4254 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4255 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4256
4257 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4258 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4260 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304261 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304262 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4263 rc = decode_get_status_resp(
4264 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4265 &currentState, &previousState, &auxState, &auxStateStatus,
4266 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4267 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4268
4269 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4270 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4272 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304273 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304274 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4275 rc = decode_get_status_resp(
4276 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4277 &currentState, &previousState, &auxState, &auxStateStatus,
4278 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4279 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4280
4281 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4282 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004283 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304284 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304285 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304286 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4287 rc = decode_get_status_resp(
4288 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4289 &currentState, &previousState, &auxState, &auxStateStatus,
4290 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4291 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4292
4293 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4294 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4295 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4296 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304297 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304298 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4299 rc = decode_get_status_resp(
4300 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4301 &currentState, &previousState, &auxState, &auxStateStatus,
4302 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4303 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4304
4305 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4306 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004307 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304308 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304309 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304310 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4311 rc = decode_get_status_resp(
4312 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4313 &currentState, &previousState, &auxState, &auxStateStatus,
4314 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4315 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4316
4317 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4318 // IDLE
4319 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4320 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4322 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304323 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304324 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4325 rc = decode_get_status_resp(
4326 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4327 &currentState, &previousState, &auxState, &auxStateStatus,
4328 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4329 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4330}
4331
4332TEST(CancelUpdateComponent, goodPathEncodeRequest)
4333{
4334 constexpr uint8_t instanceId = 9;
4335 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304336 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304337 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4338
4339 auto rc = encode_cancel_update_component_req(
4340 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4341 EXPECT_EQ(rc, PLDM_SUCCESS);
4342
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004343 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304344 EXPECT_EQ(request, outRequest);
4345}
4346
4347TEST(CancelUpdateComponent, errorPathEncodeRequest)
4348{
4349 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304350 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304351 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4352
4353 auto rc = encode_cancel_update_component_req(
4354 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4355 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4356
4357 rc = encode_cancel_update_component_req(
4358 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4359 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4360}
4361
4362TEST(CancelUpdateComponent, testGoodDecodeResponse)
4363{
4364 uint8_t completionCode = 0;
4365 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4366 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304367 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304368 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4369 cancelUpdateComponentResponse1.data());
4370 auto rc = decode_cancel_update_component_resp(
4371 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4372 &completionCode);
4373 EXPECT_EQ(rc, PLDM_SUCCESS);
4374 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4375
4376 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4377 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304378 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304379 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4380 cancelUpdateComponentResponse2.data());
4381 rc = decode_cancel_update_component_resp(
4382 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4383 &completionCode);
4384 EXPECT_EQ(rc, PLDM_SUCCESS);
4385 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4386}
4387
4388TEST(CancelUpdateComponent, testBadDecodeResponse)
4389{
4390 uint8_t completionCode = 0;
4391 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4392 0x00, 0x00, 0x00};
4393 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304394 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304395 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4396
4397 auto rc = decode_cancel_update_component_resp(
4398 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4399 &completionCode);
4400 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4401
4402 rc = decode_cancel_update_component_resp(
4403 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4404 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4405
4406 rc = decode_cancel_update_component_resp(
4407 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4408 &completionCode);
4409 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4410}
4411
4412TEST(CancelUpdate, goodPathEncodeRequest)
4413{
4414 constexpr uint8_t instanceId = 10;
4415 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304416 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304417 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4418
4419 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4420 PLDM_CANCEL_UPDATE_REQ_BYTES);
4421 EXPECT_EQ(rc, PLDM_SUCCESS);
4422
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004423 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304424 EXPECT_EQ(request, outRequest);
4425}
4426
4427TEST(CancelUpdate, errorPathEncodeRequest)
4428{
4429 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304430 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304431 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4432
4433 auto rc =
4434 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4435 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4436
4437 rc = encode_cancel_update_req(0, requestMsg,
4438 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4439 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4440}
4441
4442TEST(CancelUpdate, goodPathDecodeResponse)
4443{
4444 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4445 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4446 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4448 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304449 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304450 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4451 uint8_t completionCode = 0;
4452 bool8_t nonFunctioningComponentIndication = 0;
4453 bitfield64_t nonFunctioningComponentBitmap{0};
4454 auto rc = decode_cancel_update_resp(
4455 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4456 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4457 EXPECT_EQ(rc, PLDM_SUCCESS);
4458 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4459 EXPECT_EQ(nonFunctioningComponentIndication,
4460 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4461 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4462 nonFunctioningComponentBitmap1);
4463
4464 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4465 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4466 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4468 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304469 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304470 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4471 rc = decode_cancel_update_resp(
4472 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4473 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4474 EXPECT_EQ(rc, PLDM_SUCCESS);
4475 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4476 EXPECT_EQ(nonFunctioningComponentIndication,
4477 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4478 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4479 nonFunctioningComponentBitmap2);
4480
4481 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4482 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4483 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304484 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304485 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4486 rc = decode_cancel_update_resp(
4487 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4488 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4489 EXPECT_EQ(rc, PLDM_SUCCESS);
4490 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4491}
4492
4493TEST(CancelUpdate, errorPathDecodeResponse)
4494{
4495 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4496 0x00};
4497 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304498 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304499 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4500 uint8_t completionCode = 0;
4501 bool8_t nonFunctioningComponentIndication = 0;
4502 bitfield64_t nonFunctioningComponentBitmap{0};
4503
4504 auto rc = decode_cancel_update_resp(
4505 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4506 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4507 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4508
4509 rc = decode_cancel_update_resp(
4510 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4511 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4512 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4513
4514 rc = decode_cancel_update_resp(
4515 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4516 nullptr, &nonFunctioningComponentBitmap);
4517 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4518
4519 rc = decode_cancel_update_resp(
4520 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4521 &nonFunctioningComponentIndication, nullptr);
4522 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4523
4524 rc = decode_cancel_update_resp(
4525 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4526 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4527 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4528
4529 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4530 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4531 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304532 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304533 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4534 rc = decode_cancel_update_resp(
4535 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4536 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4537 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4538
4539 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4540 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4542 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304543 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304544 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4545 rc = decode_cancel_update_resp(
4546 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4547 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4548 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4549}