blob: 05b8dd18173d9c2c41858578932da64af53987e4 [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
Andrew Jefferya1cd72b2025-05-09 12:26:06 +09302842 maxOutstandingTransferReq = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302843 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
Sora Su06eadd02025-05-27 11:28:51 +08002960#ifdef LIBPLDM_API_TESTING
2961TEST(RequestDownstreamDeviceUpdate, goodPathEncodeRequest)
2962{
2963 constexpr uint8_t instanceId = 1;
2964
2965 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
2966 request{};
2967
2968 auto requestMsg = new (request.data()) pldm_msg;
2969
2970 constexpr struct pldm_request_downstream_device_update_req req_data = {
2971 .maximum_downstream_device_transfer_size = 512,
2972 .maximum_outstanding_transfer_requests = 2,
2973 .downstream_device_package_data_length = 0x1234,
2974 };
2975 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
2976
2977 auto rc = encode_request_downstream_device_update_req(
2978 instanceId, &req_data, requestMsg, &enc_payload_len);
2979
2980 EXPECT_EQ(rc, 0);
2981
2982 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
2983 outRequest{0x81, 0x05, 0x20, 0x00, 0x02, 0x00, 0x00, 0x02, 0x34, 0x12};
2984 EXPECT_EQ(request, outRequest);
2985}
2986#endif // LIBPLDM_API_TESTING
2987
2988#ifdef LIBPLDM_API_TESTING
2989TEST(RequestDownstreamDeviceUpdate, errorPathEncodeRequest)
2990{
2991 constexpr uint8_t instanceId = 1;
2992 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
2993
2994 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
2995 request{};
2996
2997 struct pldm_request_downstream_device_update_req req_data = {
2998 .maximum_downstream_device_transfer_size = 512,
2999 .maximum_outstanding_transfer_requests = 2,
3000 .downstream_device_package_data_length = 0x1234,
3001 };
3002
3003 auto requestMsg = new (request.data()) pldm_msg;
3004
3005 auto rc = encode_request_downstream_device_update_req(
3006 instanceId, nullptr, requestMsg, &enc_payload_len);
3007 EXPECT_EQ(rc, -EINVAL);
3008 rc = encode_request_downstream_device_update_req(
3009 instanceId, &req_data, requestMsg, &enc_payload_len);
3010 EXPECT_EQ(rc, 0);
3011
3012 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3013 nullptr, &enc_payload_len);
3014 EXPECT_EQ(rc, -EINVAL);
3015 rc = encode_request_downstream_device_update_req(
3016 instanceId, &req_data, requestMsg, &enc_payload_len);
3017 EXPECT_EQ(rc, 0);
3018
3019 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3020 requestMsg, nullptr);
3021 EXPECT_EQ(rc, -EINVAL);
3022 rc = encode_request_downstream_device_update_req(
3023 instanceId, &req_data, requestMsg, &enc_payload_len);
3024 EXPECT_EQ(rc, 0);
3025
3026 enc_payload_len =
3027 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES) - 1;
3028 rc = encode_request_downstream_device_update_req(
3029 instanceId, &req_data, requestMsg, &enc_payload_len);
3030 EXPECT_EQ(rc, -EOVERFLOW);
3031 enc_payload_len =
3032 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES);
3033 rc = encode_request_downstream_device_update_req(
3034 instanceId, &req_data, requestMsg, &enc_payload_len);
3035 EXPECT_EQ(rc, 0);
3036
3037 req_data.maximum_downstream_device_transfer_size = 31;
3038 rc = encode_request_downstream_device_update_req(
3039 instanceId, &req_data, requestMsg, &enc_payload_len);
3040 EXPECT_EQ(rc, -EINVAL);
3041 req_data.maximum_downstream_device_transfer_size =
3042 PLDM_FWUP_BASELINE_TRANSFER_SIZE;
3043
3044 req_data.maximum_outstanding_transfer_requests = 0;
3045 rc = encode_request_downstream_device_update_req(
3046 instanceId, &req_data, requestMsg, &enc_payload_len);
3047 EXPECT_EQ(rc, -EINVAL);
3048 req_data.maximum_outstanding_transfer_requests = 2;
3049 rc = encode_request_downstream_device_update_req(
3050 instanceId, &req_data, requestMsg, &enc_payload_len);
3051 EXPECT_EQ(rc, 0);
3052}
3053#endif // LIBPLDM_API_TESTING
3054
3055#ifdef LIBPLDM_API_TESTING
3056TEST(RequestDownstreamDeviceUpdate, goodPathDecodeResponse)
3057{
3058 /* Test a success completion code */
3059 constexpr uint16_t ddMetaDataLen = 1024;
3060 constexpr uint8_t ddWillSendPkgData = 1;
3061 constexpr uint16_t getPkgDataMaxTransferSize = 512;
3062 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3063 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00,
3064 0x04, 0x01, 0x00, 0x02};
3065
3066 auto responseMsg1 = new (requestUpdateResponse1.data()) pldm_msg;
3067
3068 struct pldm_request_downstream_device_update_resp resp_data1 = {
3069 .completion_code = 0,
3070 .downstream_device_meta_data_length = 0,
3071 .downstream_device_will_send_get_package_data = 0,
3072 .get_package_data_maximum_transfer_size = 0};
3073
3074 auto rc = decode_request_downstream_device_update_resp(
3075 responseMsg1, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3076 &resp_data1);
3077 EXPECT_EQ(rc, 0);
3078 EXPECT_EQ(resp_data1.completion_code, PLDM_SUCCESS);
3079 EXPECT_EQ(resp_data1.downstream_device_meta_data_length, ddMetaDataLen);
3080 EXPECT_EQ(resp_data1.downstream_device_will_send_get_package_data,
3081 ddWillSendPkgData);
3082 EXPECT_EQ(resp_data1.get_package_data_maximum_transfer_size,
3083 getPkgDataMaxTransferSize);
3084
3085 /* Test a failure completion code */
3086 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3087 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3088
3089 auto responseMsg2 = new (requestUpdateResponse2.data()) pldm_msg;
3090
3091 struct pldm_request_downstream_device_update_resp resp_data2 = {
3092 .completion_code = 0,
3093 .downstream_device_meta_data_length = 0,
3094 .downstream_device_will_send_get_package_data = 0,
3095 .get_package_data_maximum_transfer_size = 0};
3096
3097 rc = decode_request_downstream_device_update_resp(
3098 responseMsg2, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3099 &resp_data2);
3100 EXPECT_EQ(rc, 0);
3101 EXPECT_EQ(resp_data2.completion_code, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3102}
3103#endif // LIBPLDM_API_TESTING
3104
3105#ifdef LIBPLDM_API_TESTING
3106TEST(RequestDownstreamDeviceUpdate, errorPathDecodeResponse)
3107{
3108 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3109 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00,
3110 0x04, 0x01, 0x00, 0x02};
3111
3112 auto responseMsg = new (requestUpdateResponse.data()) pldm_msg;
3113
3114 struct pldm_request_downstream_device_update_resp resp_data = {
3115 .completion_code = 0,
3116 .downstream_device_meta_data_length = 0,
3117 .downstream_device_will_send_get_package_data = 0,
3118 .get_package_data_maximum_transfer_size = 0};
3119
3120 auto rc = decode_request_downstream_device_update_resp(
3121 nullptr, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, &resp_data);
3122 EXPECT_EQ(rc, -EINVAL);
3123
3124 rc = decode_request_downstream_device_update_resp(
3125 responseMsg, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, nullptr);
3126 EXPECT_EQ(rc, -EINVAL);
3127
3128 rc = decode_request_downstream_device_update_resp(responseMsg, 0,
3129 &resp_data);
3130 EXPECT_EQ(rc, -EOVERFLOW);
3131}
3132#endif // LIBPLDM_API_TESTING
3133
Andrew Jeffery9c766792022-08-10 23:12:49 +09303134TEST(PassComponentTable, goodPathEncodeRequest)
3135{
3136 constexpr uint8_t instanceId = 1;
3137 constexpr uint16_t compIdentifier = 400;
3138 constexpr uint8_t compClassificationIndex = 40;
3139 constexpr uint32_t compComparisonStamp = 0x12345678;
3140 constexpr std::string_view compVerStr = "0penBmcv1.1";
3141 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3142 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303143 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303144 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3145 compVerStrInfo.length = compVerStrLen;
3146
3147 std::array<uint8_t,
3148 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3149 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303150 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303151 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3152
3153 auto rc = encode_pass_component_table_req(
3154 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3155 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3156 compVerStrLen, &compVerStrInfo, requestMsg,
3157 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3158 EXPECT_EQ(rc, PLDM_SUCCESS);
3159
3160 std::array<uint8_t,
3161 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003162 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
3163 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
3164 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303165 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003166
3167#ifdef LIBPLDM_API_TESTING
3168 /* Check the roundtrip */
3169 struct pldm_pass_component_table_req_full req;
3170 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3171 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3172 rc =
3173 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
3174 ASSERT_EQ(rc, 0);
3175
3176 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
3177 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3178 EXPECT_EQ(req.comp_identifier, compIdentifier);
3179 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3180 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3181 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3182 EXPECT_EQ(req.version.str_len, compVerStrLen);
3183 EXPECT_TRUE(std::equal(req.version.str_data,
3184 req.version.str_data + req.version.str_len,
3185 compVerStr.data()));
3186#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303187}
3188
3189TEST(PassComponentTable, errorPathEncodeRequest)
3190{
3191 constexpr uint8_t instanceId = 1;
3192 constexpr uint16_t compIdentifier = 400;
3193 constexpr uint8_t compClassificationIndex = 40;
3194 constexpr uint32_t compComparisonStamp = 0x12345678;
3195 constexpr std::string_view compVerStr = "0penBmcv1.1";
3196 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3197 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303198 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303199 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3200 compVerStrInfo.length = compVerStrLen;
3201
3202 std::array<uint8_t,
3203 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3204 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303205 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303206 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3207
3208 auto rc = encode_pass_component_table_req(
3209 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3210 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3211 compVerStrLen, nullptr, requestMsg,
3212 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3213 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3214
3215 compVerStrInfo.ptr = nullptr;
3216 rc = encode_pass_component_table_req(
3217 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3218 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3219 compVerStrLen, &compVerStrInfo, requestMsg,
3220 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3221 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303222 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303223 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3224
3225 rc = encode_pass_component_table_req(
3226 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3227 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3228 compVerStrLen, &compVerStrInfo, nullptr,
3229 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3230 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3231
3232 rc = encode_pass_component_table_req(
3233 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3234 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3235 compVerStrLen, &compVerStrInfo, requestMsg,
3236 sizeof(pldm_pass_component_table_req));
3237 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3238
3239 rc = encode_pass_component_table_req(
3240 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3241 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3242 &compVerStrInfo, requestMsg,
3243 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3244 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3245
3246 rc = encode_pass_component_table_req(
3247 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3248 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3249 compVerStrLen - 1, &compVerStrInfo, requestMsg,
3250 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3252
3253 rc = encode_pass_component_table_req(
3254 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3255 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3256 compVerStrLen, &compVerStrInfo, requestMsg,
3257 sizeof(pldm_pass_component_table_req) + compVerStrLen);
Manojkiran Eda3643e742025-05-19 12:03:54 +05303258 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG);
Andrew Jeffery9c766792022-08-10 23:12:49 +09303259
3260 rc = encode_pass_component_table_req(
3261 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3262 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3263 compVerStrLen, &compVerStrInfo, requestMsg,
3264 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3265 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3266}
3267
3268TEST(PassComponentTable, goodPathDecodeResponse)
3269{
3270 constexpr std::array<uint8_t,
3271 hdrSize + sizeof(pldm_pass_component_table_resp)>
3272 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3273 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303274 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303275 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3276
3277 uint8_t completionCode = 0;
3278 uint8_t compResp = 0;
3279 uint8_t compRespCode = 0;
3280
3281 auto rc = decode_pass_component_table_resp(
3282 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3283 &compResp, &compRespCode);
3284
3285 EXPECT_EQ(rc, PLDM_SUCCESS);
3286 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3287 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3288 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3289
3290 constexpr std::array<uint8_t,
3291 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003292 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303293 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303294 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303295 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3296 rc = decode_pass_component_table_resp(
3297 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3298 &compResp, &compRespCode);
3299
3300 EXPECT_EQ(rc, PLDM_SUCCESS);
3301 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3302 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3303 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3304
3305 constexpr std::array<uint8_t,
3306 hdrSize + sizeof(pldm_pass_component_table_resp)>
3307 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3308 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303309 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303310 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3311
3312 rc = decode_pass_component_table_resp(
3313 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3314 &compResp, &compRespCode);
3315
3316 EXPECT_EQ(rc, PLDM_SUCCESS);
3317 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3318}
3319
3320TEST(PassComponentTable, errorPathDecodeResponse)
3321{
3322 constexpr std::array<uint8_t,
3323 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3324 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3325 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303326 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303327 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3328
3329 uint8_t completionCode = 0;
3330 uint8_t compResp = 0;
3331 uint8_t compRespCode = 0;
3332
3333 auto rc = decode_pass_component_table_resp(
3334 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3335 &compResp, &compRespCode);
3336 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3337
3338 rc = decode_pass_component_table_resp(
3339 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3340 &compResp, &compRespCode);
3341 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3342
3343 rc = decode_pass_component_table_resp(
3344 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3345 &completionCode, nullptr, &compRespCode);
3346 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3347
3348 rc = decode_pass_component_table_resp(
3349 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3350 &completionCode, &compResp, nullptr);
3351 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3352
3353 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3354 &compResp, &compRespCode);
3355 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3356
3357 rc = decode_pass_component_table_resp(
3358 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3359 &completionCode, &compResp, &compRespCode);
3360 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3361
3362 constexpr std::array<uint8_t,
3363 hdrSize + sizeof(pldm_pass_component_table_resp)>
3364 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3365 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303366 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303367 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3368 rc = decode_pass_component_table_resp(
3369 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3370 &compResp, &compRespCode);
3371 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3372
3373 constexpr std::array<uint8_t,
3374 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003375 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303376 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303377 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303378 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3379 rc = decode_pass_component_table_resp(
3380 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3381 &compResp, &compRespCode);
3382 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3383
3384 constexpr std::array<uint8_t,
3385 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003386 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303387 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303388 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303389 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3390 rc = decode_pass_component_table_resp(
3391 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3392 &compResp, &compRespCode);
3393 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3394}
3395
3396TEST(UpdateComponent, goodPathEncodeRequest)
3397{
3398 constexpr uint8_t instanceId = 2;
3399 constexpr uint16_t compIdentifier = 500;
3400 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003401 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303402 constexpr uint32_t compImageSize = 4096;
3403 constexpr bitfield32_t updateOptionFlags{1};
3404 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3405 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3406 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303407 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303408 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3409 compVerStrInfo.length = compVerStrLen;
3410
3411 std::array<uint8_t,
3412 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3413 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303414 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303415 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3416
3417 auto rc = encode_update_component_req(
3418 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3419 compComparisonStamp, compImageSize, updateOptionFlags,
3420 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3421 sizeof(pldm_update_component_req) + compVerStrLen);
3422 EXPECT_EQ(rc, PLDM_SUCCESS);
3423
3424 std::array<uint8_t,
3425 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003426 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3427 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3428 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3429 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303430 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003431
3432#ifdef LIBPLDM_API_TESTING
3433 /* Check the roundtrip */
3434 struct pldm_update_component_req_full req;
3435 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3436 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3437 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3438 ASSERT_EQ(rc, 0);
3439
3440 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3441 EXPECT_EQ(req.comp_identifier, compIdentifier);
3442 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3443 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3444 EXPECT_EQ(req.comp_image_size, compImageSize);
3445 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3446 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3447 EXPECT_EQ(req.version.str_len, compVerStrLen);
3448 EXPECT_TRUE(std::equal(req.version.str_data,
3449 req.version.str_data + req.version.str_len,
3450 compVerStr.data()));
3451#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303452}
3453
3454TEST(UpdateComponent, errorPathEncodeRequest)
3455{
3456 constexpr uint8_t instanceId = 2;
3457 constexpr uint16_t compIdentifier = 500;
3458 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003459 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303460 constexpr uint32_t compImageSize = 4096;
3461 constexpr bitfield32_t updateOptionFlags{1};
3462 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3463 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3464 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303465 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303466 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3467 compVerStrInfo.length = compVerStrLen;
3468
3469 std::array<uint8_t,
3470 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3471 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303472 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303473 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3474
3475 auto rc = encode_update_component_req(
3476 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3477 compComparisonStamp, compImageSize, updateOptionFlags,
3478 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3479 sizeof(pldm_update_component_req) + compVerStrLen);
3480 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3481
3482 compVerStrInfo.ptr = nullptr;
3483 rc = encode_update_component_req(
3484 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3485 compComparisonStamp, compImageSize, updateOptionFlags,
3486 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3487 sizeof(pldm_update_component_req) + compVerStrLen);
3488 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303489 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303490 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3491
3492 rc = encode_update_component_req(
3493 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3494 compComparisonStamp, compImageSize, updateOptionFlags,
3495 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3496 sizeof(pldm_update_component_req) + compVerStrLen);
3497 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3498
3499 rc = encode_update_component_req(
3500 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3501 compComparisonStamp, compImageSize, updateOptionFlags,
3502 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3503 sizeof(pldm_update_component_req));
3504 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3505
3506 rc = encode_update_component_req(
3507 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3508 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3509 compVerStrLen, &compVerStrInfo, requestMsg,
3510 sizeof(pldm_update_component_req) + compVerStrLen);
3511 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3512
3513 rc = encode_update_component_req(
3514 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3515 compComparisonStamp, compImageSize, updateOptionFlags,
3516 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3517 sizeof(pldm_update_component_req) + compVerStrLen);
3518 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3519
3520 rc = encode_update_component_req(
3521 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3522 compComparisonStamp, compImageSize, updateOptionFlags,
3523 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3524 sizeof(pldm_update_component_req) + compVerStrLen);
3525 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3526
3527 rc = encode_update_component_req(
3528 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3529 compComparisonStamp, compImageSize, updateOptionFlags,
3530 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3531 sizeof(pldm_update_component_req) + compVerStrLen);
3532 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3533}
3534
3535TEST(UpdateComponent, goodPathDecodeResponse)
3536{
3537 constexpr std::bitset<32> forceUpdateComp{1};
3538 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3539 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3540 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3541 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3542 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303543 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303544 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3545
3546 uint8_t completionCode = 0;
3547 uint8_t compCompatibilityResp = 0;
3548 uint8_t compCompatibilityRespCode = 0;
3549 bitfield32_t updateOptionFlagsEnabled{};
3550 uint16_t timeBeforeReqFWData = 0;
3551
3552 auto rc = decode_update_component_resp(
3553 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3554 &compCompatibilityResp, &compCompatibilityRespCode,
3555 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3556
3557 EXPECT_EQ(rc, PLDM_SUCCESS);
3558 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3559 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3560 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3561 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3562 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3563
3564 constexpr std::bitset<32> noFlags{};
3565 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3566 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3567 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3569 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303570 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303571 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3572 rc = decode_update_component_resp(
3573 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3574 &compCompatibilityResp, &compCompatibilityRespCode,
3575 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3576
3577 EXPECT_EQ(rc, PLDM_SUCCESS);
3578 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3579 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3580 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3581 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3582 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3583
3584 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3585 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3586 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303587 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303588 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3589
3590 rc = decode_update_component_resp(
3591 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3592 &compCompatibilityResp, &compCompatibilityRespCode,
3593 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3594
3595 EXPECT_EQ(rc, PLDM_SUCCESS);
3596 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3597}
3598
3599TEST(UpdateComponent, errorPathDecodeResponse)
3600{
3601 constexpr std::array<uint8_t,
3602 hdrSize + sizeof(pldm_update_component_resp) - 1>
3603 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3604 0x00, 0x00, 0x00, 0x00, 0x00};
3605 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303606 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303607 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3608
3609 uint8_t completionCode = 0;
3610 uint8_t compCompatibilityResp = 0;
3611 uint8_t compCompatibilityRespCode = 0;
3612 bitfield32_t updateOptionFlagsEnabled{};
3613 uint16_t timeBeforeReqFWData = 0;
3614
3615 auto rc = decode_update_component_resp(
3616 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3617 &compCompatibilityResp, &compCompatibilityRespCode,
3618 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3619 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3620
3621 rc = decode_update_component_resp(
3622 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3623 &compCompatibilityResp, &compCompatibilityRespCode,
3624 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3625 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3626
3627 rc = decode_update_component_resp(
3628 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3629 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3630 &timeBeforeReqFWData);
3631 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3632
3633 rc = decode_update_component_resp(
3634 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3635 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3636 &timeBeforeReqFWData);
3637 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3638
3639 rc = decode_update_component_resp(
3640 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3641 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3642 &timeBeforeReqFWData);
3643 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3644
3645 rc = decode_update_component_resp(
3646 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3647 &compCompatibilityResp, &compCompatibilityRespCode,
3648 &updateOptionFlagsEnabled, nullptr);
3649 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3650
3651 rc = decode_update_component_resp(
3652 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3653 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3654 &timeBeforeReqFWData);
3655 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3656
3657 rc = decode_update_component_resp(
3658 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3659 &compCompatibilityResp, &compCompatibilityRespCode,
3660 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3661 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3662
3663 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3664 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3665 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3666 auto responseMsg2 =
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*>(updateComponentResponse2.data());
3669 rc = decode_update_component_resp(
3670 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3671 &compCompatibilityResp, &compCompatibilityRespCode,
3672 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3673 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3674
3675 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003676 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303677 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3678 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303679 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303680 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3681 rc = decode_update_component_resp(
3682 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3683 &compCompatibilityResp, &compCompatibilityRespCode,
3684 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3685 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3686
3687 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003688 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303689 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3690 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303691 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303692 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3693 rc = decode_update_component_resp(
3694 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3695 &compCompatibilityResp, &compCompatibilityRespCode,
3696 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3697 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3698}
3699
3700TEST(RequestFirmwareData, goodPathDecodeRequest)
3701{
3702 constexpr uint32_t offset = 300;
3703 constexpr uint32_t length = 255;
3704 constexpr std::array<uint8_t,
3705 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003706 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3707 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303708 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303709 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3710
3711 uint32_t outOffset = 0;
3712 uint32_t outLength = 0;
3713 auto rc = decode_request_firmware_data_req(
3714 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3715 &outLength);
3716
3717 EXPECT_EQ(rc, PLDM_SUCCESS);
3718 EXPECT_EQ(outOffset, offset);
3719 EXPECT_EQ(outLength, length);
3720}
3721
3722TEST(RequestFirmwareData, errorPathDecodeRequest)
3723{
3724 constexpr std::array<uint8_t,
3725 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003726 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3727 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303728 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303729 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3730
3731 uint32_t outOffset = 0;
3732 uint32_t outLength = 0;
3733 auto rc = decode_request_firmware_data_req(
3734 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3735 &outLength);
3736 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3737
3738 rc = decode_request_firmware_data_req(
3739 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3740 &outLength);
3741 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3742
3743 rc = decode_request_firmware_data_req(
3744 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3745 nullptr);
3746 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3747
3748 rc = decode_request_firmware_data_req(
3749 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3750 &outLength);
3751 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3752
3753 rc = decode_request_firmware_data_req(
3754 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3755 &outLength);
3756 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3757}
3758
3759TEST(RequestFirmwareData, goodPathEncodeResponse)
3760{
3761 constexpr uint8_t instanceId = 3;
3762 constexpr uint8_t completionCode = PLDM_SUCCESS;
3763 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3764 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3765 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003766 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3767 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3768 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3769 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303770 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3771 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3772 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003773 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3774 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3775 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3776 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303777 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303778 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3779 auto rc = encode_request_firmware_data_resp(
3780 instanceId, completionCode, responseMsg1,
3781 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3782 EXPECT_EQ(rc, PLDM_SUCCESS);
3783 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3784
3785 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3786 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3787 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3788 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303789 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303790 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3791 rc = encode_request_firmware_data_resp(
3792 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3793 sizeof(completionCode));
3794 EXPECT_EQ(rc, PLDM_SUCCESS);
3795 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3796}
3797
3798TEST(RequestFirmwareData, errorPathEncodeResponse)
3799{
3800 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303801 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303802 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3803 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3804 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3805
3806 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3807 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3808}
3809
3810TEST(TransferComplete, goodPathDecodeRequest)
3811{
3812 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3813 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3814 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3815 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303816 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303817 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3818 uint8_t outTransferResult = 0;
3819
3820 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3821 &outTransferResult);
3822 EXPECT_EQ(rc, PLDM_SUCCESS);
3823 EXPECT_EQ(outTransferResult, transferResult);
3824
3825 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3826 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3827 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303828 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303829 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3830 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3831 &outTransferResult);
3832 EXPECT_EQ(rc, PLDM_SUCCESS);
3833 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3834}
3835
3836TEST(TransferComplete, errorPathDecodeRequest)
3837{
3838 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3839 0x00};
3840 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303841 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303842 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3843 uint8_t outTransferResult = 0;
3844
3845 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3846 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3847
3848 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3849 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3850
3851 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3852 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3853}
3854
3855TEST(TransferComplete, goodPathEncodeResponse)
3856{
3857 constexpr uint8_t instanceId = 4;
3858 constexpr uint8_t completionCode = PLDM_SUCCESS;
3859 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3860 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3861 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3862 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3863 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303864 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303865 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3866 auto rc = encode_transfer_complete_resp(
3867 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3868 EXPECT_EQ(rc, PLDM_SUCCESS);
3869 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3870
3871 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3872 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3873 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3874 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3875 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303876 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303877 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3878 rc = encode_transfer_complete_resp(instanceId,
3879 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3880 responseMsg2, sizeof(completionCode));
3881 EXPECT_EQ(rc, PLDM_SUCCESS);
3882 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3883}
3884
3885TEST(TransferComplete, errorPathEncodeResponse)
3886{
3887 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3888 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303889 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303890 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3891 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3892 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3893
3894 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3895 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3896}
3897
3898TEST(VerifyComplete, goodPathDecodeRequest)
3899{
3900 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3901 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3902 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3903 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303904 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303905 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3906 uint8_t outVerifyResult = 0;
3907
3908 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3909 &outVerifyResult);
3910 EXPECT_EQ(rc, PLDM_SUCCESS);
3911 EXPECT_EQ(outVerifyResult, verifyResult);
3912
3913 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3914 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3915 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303916 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303917 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
3918 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
3919 &outVerifyResult);
3920 EXPECT_EQ(rc, PLDM_SUCCESS);
3921 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
3922}
3923
3924TEST(VerifyComplete, errorPathDecodeRequest)
3925{
3926 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
3927 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303928 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303929 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
3930 uint8_t outVerifyResult = 0;
3931
3932 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
3933 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3934
3935 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
3936 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3937
3938 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
3939 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3940}
3941
3942TEST(VerifyComplete, goodPathEncodeResponse)
3943{
3944 constexpr uint8_t instanceId = 5;
3945 constexpr uint8_t completionCode = PLDM_SUCCESS;
3946 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3947 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
3948 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3949 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3950 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303951 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303952 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
3953 auto rc = encode_verify_complete_resp(instanceId, completionCode,
3954 responseMsg1, sizeof(completionCode));
3955 EXPECT_EQ(rc, PLDM_SUCCESS);
3956 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
3957
3958 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3959 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
3960 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3961 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3962 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303963 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303964 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
3965 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
3966 responseMsg2, sizeof(completionCode));
3967 EXPECT_EQ(rc, PLDM_SUCCESS);
3968 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
3969}
3970
3971TEST(VerifyComplete, errorPathEncodeResponse)
3972{
3973 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
3974 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303975 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303976 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
3977 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3978 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3979
3980 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3981 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3982}
3983
3984TEST(ApplyComplete, goodPathDecodeRequest)
3985{
3986 constexpr uint8_t applyResult1 =
3987 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
3988 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
3989 constexpr std::bitset<16> compActivationModification1{0x30};
3990 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
3991 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
3992 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303993 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303994 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
3995 uint8_t outApplyResult = 0;
3996 bitfield16_t outCompActivationModification{};
3997 auto rc = decode_apply_complete_req(
3998 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
3999 &outCompActivationModification);
4000 EXPECT_EQ(rc, PLDM_SUCCESS);
4001 EXPECT_EQ(outApplyResult, applyResult1);
4002 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
4003
4004 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
4005 constexpr std::bitset<16> compActivationModification2{};
4006 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4007 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4008 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304009 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304010 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4011 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4012 &outApplyResult,
4013 &outCompActivationModification);
4014 EXPECT_EQ(rc, PLDM_SUCCESS);
4015 EXPECT_EQ(outApplyResult, applyResult2);
4016 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
4017}
4018
4019TEST(ApplyComplete, errorPathDecodeRequest)
4020{
4021 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
4022 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304023 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304024 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4025 uint8_t outApplyResult = 0;
4026 bitfield16_t outCompActivationModification{};
4027
4028 auto rc = decode_apply_complete_req(
4029 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
4030 &outCompActivationModification);
4031 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4032
4033 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4034 nullptr, &outCompActivationModification);
4035 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4036
4037 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4038 &outApplyResult, nullptr);
4039 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4040
4041 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
4042 &outCompActivationModification);
4043 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4044
4045 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4046 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
4047 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304048 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304049 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4050 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4051 &outApplyResult,
4052 &outCompActivationModification);
4053 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4054}
4055
4056TEST(ApplyComplete, goodPathEncodeResponse)
4057{
4058 constexpr uint8_t instanceId = 6;
4059 constexpr uint8_t completionCode = PLDM_SUCCESS;
4060 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4061 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
4062 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4063 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4064 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304065 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304066 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
4067 auto rc = encode_apply_complete_resp(instanceId, completionCode,
4068 responseMsg1, sizeof(completionCode));
4069 EXPECT_EQ(rc, PLDM_SUCCESS);
4070 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
4071
4072 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4073 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
4074 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4075 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4076 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304077 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304078 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
4079 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4080 responseMsg2, sizeof(completionCode));
4081 EXPECT_EQ(rc, PLDM_SUCCESS);
4082 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
4083}
4084
4085TEST(ApplyComplete, errorPathEncodeResponse)
4086{
4087 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
4088 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304089 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304090 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
4091 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4092 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4093
4094 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4095 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4096}
4097
4098TEST(ActivateFirmware, goodPathEncodeRequest)
4099{
4100 constexpr uint8_t instanceId = 7;
4101
4102 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304103 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304104 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4105
4106 auto rc = encode_activate_firmware_req(
4107 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
4108 sizeof(pldm_activate_firmware_req));
4109 EXPECT_EQ(rc, PLDM_SUCCESS);
4110
4111 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004112 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304113 EXPECT_EQ(request, outRequest);
4114}
4115
4116TEST(ActivateFirmware, errorPathEncodeRequest)
4117{
4118 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304119 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304120 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4121
4122 auto rc = encode_activate_firmware_req(
4123 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
4124 sizeof(pldm_activate_firmware_req));
4125 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4126
4127 rc = encode_activate_firmware_req(
4128 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
4129 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4130
4131 rc = encode_activate_firmware_req(0, 2, requestMsg,
4132 sizeof(pldm_activate_firmware_req));
4133 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4134}
4135
4136TEST(ActivateFirmware, goodPathDecodeResponse)
4137{
4138 constexpr uint16_t estimatedTimeForActivation100s = 100;
4139 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4140 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
4141 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304142 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304143 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
4144
4145 uint8_t completionCode = 0;
4146 uint16_t estimatedTimeForActivation = 0;
4147
4148 auto rc = decode_activate_firmware_resp(
4149 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
4150 &estimatedTimeForActivation);
4151
4152 EXPECT_EQ(rc, PLDM_SUCCESS);
4153 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4154 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
4155
4156 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4157 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
4158 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304159 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304160 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
4161
4162 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
4163 &completionCode,
4164 &estimatedTimeForActivation);
4165
4166 EXPECT_EQ(rc, PLDM_SUCCESS);
4167 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
4168}
4169
4170TEST(ActivateFirmware, errorPathDecodeResponse)
4171{
4172 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4173 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4174 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304175 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304176 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
4177
4178 uint8_t completionCode = 0;
4179 uint16_t estimatedTimeForActivation = 0;
4180
4181 auto rc = decode_activate_firmware_resp(
4182 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
4183 &estimatedTimeForActivation);
4184 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4185
4186 rc = decode_activate_firmware_resp(responseMsg,
4187 sizeof(pldm_activate_firmware_resp),
4188 nullptr, &estimatedTimeForActivation);
4189 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4190
4191 rc = decode_activate_firmware_resp(responseMsg,
4192 sizeof(pldm_activate_firmware_resp),
4193 &completionCode, nullptr);
4194 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4195
4196 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
4197 &estimatedTimeForActivation);
4198 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4199
4200 rc = decode_activate_firmware_resp(
4201 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
4202 &estimatedTimeForActivation);
4203 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4204}
4205
4206TEST(GetStatus, goodPathEncodeRequest)
4207{
4208 constexpr uint8_t instanceId = 8;
4209 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304210 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304211 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4212
4213 auto rc = encode_get_status_req(instanceId, requestMsg,
4214 PLDM_GET_STATUS_REQ_BYTES);
4215 EXPECT_EQ(rc, PLDM_SUCCESS);
4216
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004217 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304218 EXPECT_EQ(request, outRequest);
4219}
4220
4221TEST(GetStatus, errorPathEncodeRequest)
4222{
4223 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304224 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304225 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4226
4227 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4228 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4229
4230 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4231 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4232}
4233
4234TEST(GetStatus, goodPathDecodeResponse)
4235{
4236 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4237 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4238 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4239 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4240 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304241 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304242 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4243
4244 uint8_t completionCode = 0;
4245 uint8_t currentState = 0;
4246 uint8_t previousState = 0;
4247 uint8_t auxState = 0;
4248 uint8_t auxStateStatus = 0;
4249 uint8_t progressPercent = 0;
4250 uint8_t reasonCode = 0;
4251 bitfield32_t updateOptionFlagsEnabled{0};
4252
4253 auto rc = decode_get_status_resp(
4254 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4255 &currentState, &previousState, &auxState, &auxStateStatus,
4256 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4257
4258 EXPECT_EQ(rc, PLDM_SUCCESS);
4259 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4260 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4261 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4262 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4263 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4264 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4265 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4266 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4267
4268 // Bit position 0 - Force update of component – FD will perform a force
4269 // update of the component.
4270 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4271 constexpr uint8_t progressPercent2 = 50;
4272 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4273 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4274 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4275 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304276 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304277 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4278
4279 rc = decode_get_status_resp(
4280 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4281 &currentState, &previousState, &auxState, &auxStateStatus,
4282 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4283
4284 EXPECT_EQ(rc, PLDM_SUCCESS);
4285 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4286 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4287 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4288 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4289 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4290 EXPECT_EQ(progressPercent, progressPercent2);
4291 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4292 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4293
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004294#ifdef LIBPLDM_API_TESTING
4295 /* Check the roundtrip */
4296 PLDM_MSG_DEFINE_P(enc, 1000);
4297 size_t enc_payload_len = 1000;
4298 const struct pldm_get_status_resp status_enc = {
4299 .completion_code = PLDM_SUCCESS,
4300 .current_state = currentState,
4301 .previous_state = previousState,
4302 .aux_state = auxState,
4303 .aux_state_status = auxStateStatus,
4304 .progress_percent = progressPercent,
4305 .reason_code = reasonCode,
4306 .update_option_flags_enabled = updateOptionFlagsEnabled,
4307 };
4308 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4309 &enc_payload_len);
4310 EXPECT_EQ(rc, PLDM_SUCCESS);
4311 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4312 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4313 getStatusResponse2.end(), enc_buf + hdrSize));
4314 check_response(enc, PLDM_GET_STATUS);
4315#endif
4316
4317 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304318 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4319 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4320 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304321 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304322 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4323 rc = decode_get_status_resp(
4324 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4325 &currentState, &previousState, &auxState, &auxStateStatus,
4326 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4327 EXPECT_EQ(rc, PLDM_SUCCESS);
4328 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4329}
4330
4331TEST(GetStatus, errorPathDecodeResponse)
4332{
4333 uint8_t completionCode = 0;
4334 uint8_t currentState = 0;
4335 uint8_t previousState = 0;
4336 uint8_t auxState = 0;
4337 uint8_t auxStateStatus = 0;
4338 uint8_t progressPercent = 0;
4339 uint8_t reasonCode = 0;
4340 bitfield32_t updateOptionFlagsEnabled{0};
4341
4342 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4343 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304344 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304345 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4346
4347 auto rc = decode_get_status_resp(
4348 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4349 &currentState, &previousState, &auxState, &auxStateStatus,
4350 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4351 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4352
4353 rc = decode_get_status_resp(
4354 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4355 &currentState, &previousState, &auxState, &auxStateStatus,
4356 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4357 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4358
4359 rc = decode_get_status_resp(
4360 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4361 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4362 &reasonCode, &updateOptionFlagsEnabled);
4363 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4364
4365 rc = decode_get_status_resp(
4366 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4367 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4368 &reasonCode, &updateOptionFlagsEnabled);
4369 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4370
4371 rc = decode_get_status_resp(
4372 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4373 &currentState, &previousState, nullptr, &auxStateStatus,
4374 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4375 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4376
4377 rc = decode_get_status_resp(
4378 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4379 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4380 &reasonCode, &updateOptionFlagsEnabled);
4381 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4382
4383 rc = decode_get_status_resp(
4384 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4385 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4386 &reasonCode, &updateOptionFlagsEnabled);
4387 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4388
4389 rc = decode_get_status_resp(
4390 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4391 &currentState, &previousState, &auxState, &auxStateStatus,
4392 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4393 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4394
4395 rc = decode_get_status_resp(
4396 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4397 &currentState, &previousState, &auxState, &auxStateStatus,
4398 &progressPercent, &reasonCode, nullptr);
4399 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4400
4401 rc = decode_get_status_resp(
4402 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4403 &currentState, &previousState, &auxState, &auxStateStatus,
4404 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4405 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4406
4407 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4408 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4410 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304411 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304412 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4413 rc = decode_get_status_resp(
4414 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4415 &currentState, &previousState, &auxState, &auxStateStatus,
4416 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4417 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4418
4419 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4420 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4422 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304423 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304424 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4425 rc = decode_get_status_resp(
4426 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4427 &currentState, &previousState, &auxState, &auxStateStatus,
4428 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4429 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4430
4431 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4432 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4433 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4434 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304435 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304436 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4437 rc = decode_get_status_resp(
4438 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4439 &currentState, &previousState, &auxState, &auxStateStatus,
4440 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4441 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4442
4443 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4444 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4446 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304448 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4449 rc = decode_get_status_resp(
4450 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4451 &currentState, &previousState, &auxState, &auxStateStatus,
4452 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4453 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4454
4455 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4456 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004457 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304458 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304459 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304460 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4461 rc = decode_get_status_resp(
4462 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4463 &currentState, &previousState, &auxState, &auxStateStatus,
4464 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4465 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4466
4467 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4468 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4469 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4470 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304471 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304472 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4473 rc = decode_get_status_resp(
4474 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4475 &currentState, &previousState, &auxState, &auxStateStatus,
4476 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4477 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4478
4479 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4480 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004481 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304482 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304483 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304484 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4485 rc = decode_get_status_resp(
4486 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4487 &currentState, &previousState, &auxState, &auxStateStatus,
4488 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4489 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4490
4491 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4492 // IDLE
4493 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4494 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4496 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304497 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304498 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4499 rc = decode_get_status_resp(
4500 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4501 &currentState, &previousState, &auxState, &auxStateStatus,
4502 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4503 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4504}
4505
4506TEST(CancelUpdateComponent, goodPathEncodeRequest)
4507{
4508 constexpr uint8_t instanceId = 9;
4509 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304510 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304511 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4512
4513 auto rc = encode_cancel_update_component_req(
4514 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4515 EXPECT_EQ(rc, PLDM_SUCCESS);
4516
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004517 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304518 EXPECT_EQ(request, outRequest);
4519}
4520
4521TEST(CancelUpdateComponent, errorPathEncodeRequest)
4522{
4523 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304524 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304525 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4526
4527 auto rc = encode_cancel_update_component_req(
4528 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4529 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4530
4531 rc = encode_cancel_update_component_req(
4532 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4533 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4534}
4535
4536TEST(CancelUpdateComponent, testGoodDecodeResponse)
4537{
4538 uint8_t completionCode = 0;
4539 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4540 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304541 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304542 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4543 cancelUpdateComponentResponse1.data());
4544 auto rc = decode_cancel_update_component_resp(
4545 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4546 &completionCode);
4547 EXPECT_EQ(rc, PLDM_SUCCESS);
4548 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4549
4550 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4551 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304552 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304553 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4554 cancelUpdateComponentResponse2.data());
4555 rc = decode_cancel_update_component_resp(
4556 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4557 &completionCode);
4558 EXPECT_EQ(rc, PLDM_SUCCESS);
4559 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4560}
4561
4562TEST(CancelUpdateComponent, testBadDecodeResponse)
4563{
4564 uint8_t completionCode = 0;
4565 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4566 0x00, 0x00, 0x00};
4567 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304568 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304569 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4570
4571 auto rc = decode_cancel_update_component_resp(
4572 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4573 &completionCode);
4574 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4575
4576 rc = decode_cancel_update_component_resp(
4577 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4578 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4579
4580 rc = decode_cancel_update_component_resp(
4581 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4582 &completionCode);
4583 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4584}
4585
4586TEST(CancelUpdate, goodPathEncodeRequest)
4587{
4588 constexpr uint8_t instanceId = 10;
4589 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304590 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304591 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4592
4593 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4594 PLDM_CANCEL_UPDATE_REQ_BYTES);
4595 EXPECT_EQ(rc, PLDM_SUCCESS);
4596
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004597 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304598 EXPECT_EQ(request, outRequest);
4599}
4600
4601TEST(CancelUpdate, errorPathEncodeRequest)
4602{
4603 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304604 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304605 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4606
4607 auto rc =
4608 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4609 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4610
4611 rc = encode_cancel_update_req(0, requestMsg,
4612 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4613 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4614}
4615
4616TEST(CancelUpdate, goodPathDecodeResponse)
4617{
4618 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4619 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4620 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4622 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304623 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304624 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4625 uint8_t completionCode = 0;
4626 bool8_t nonFunctioningComponentIndication = 0;
4627 bitfield64_t nonFunctioningComponentBitmap{0};
4628 auto rc = decode_cancel_update_resp(
4629 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4630 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4631 EXPECT_EQ(rc, PLDM_SUCCESS);
4632 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4633 EXPECT_EQ(nonFunctioningComponentIndication,
4634 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4635 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4636 nonFunctioningComponentBitmap1);
4637
4638 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4639 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4640 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4642 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304643 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304644 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4645 rc = decode_cancel_update_resp(
4646 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4647 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4648 EXPECT_EQ(rc, PLDM_SUCCESS);
4649 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4650 EXPECT_EQ(nonFunctioningComponentIndication,
4651 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4652 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4653 nonFunctioningComponentBitmap2);
4654
4655 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4656 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4657 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304658 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304659 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4660 rc = decode_cancel_update_resp(
4661 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4662 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4663 EXPECT_EQ(rc, PLDM_SUCCESS);
4664 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4665}
4666
4667TEST(CancelUpdate, errorPathDecodeResponse)
4668{
4669 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4670 0x00};
4671 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304672 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304673 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4674 uint8_t completionCode = 0;
4675 bool8_t nonFunctioningComponentIndication = 0;
4676 bitfield64_t nonFunctioningComponentBitmap{0};
4677
4678 auto rc = decode_cancel_update_resp(
4679 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4680 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4681 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4682
4683 rc = decode_cancel_update_resp(
4684 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4685 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4686 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4687
4688 rc = decode_cancel_update_resp(
4689 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4690 nullptr, &nonFunctioningComponentBitmap);
4691 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4692
4693 rc = decode_cancel_update_resp(
4694 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4695 &nonFunctioningComponentIndication, nullptr);
4696 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4697
4698 rc = decode_cancel_update_resp(
4699 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4700 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4701 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4702
4703 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4704 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4705 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304706 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304707 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4708 rc = decode_cancel_update_resp(
4709 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4710 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4711 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4712
4713 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4714 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4716 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304717 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304718 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4719 rc = decode_cancel_update_resp(
4720 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4721 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4722 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4723}