blob: 4e165522ab6fc8b0b735bd845d92e7155d301b9f [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;
Andrew Jeffery2613c272025-03-12 14:15:41 +103051
52static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
53 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1{
54 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
55 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a,
56 };
57
Carter Chenf72cf6f2025-06-24 15:34:49 +080058static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
59 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2{0x31, 0x19, 0xce, 0x2f, 0xe8, 0x0a,
60 0x4a, 0x99, 0xaf, 0x6d, 0x46, 0xf8,
61 0xb1, 0x21, 0xf6, 0xbf};
62
Andrew Jeffery150b06c2025-03-12 14:17:42 +103063static constexpr size_t PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 = 43;
64
65static constexpr std::array<uint8_t, PLDM_TIMESTAMP104_SIZE>
66 testPackageReleaseDateTime{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
Andrew Jefferye038b962025-03-06 16:04:59 +103068
Andrew Jeffery9c766792022-08-10 23:12:49 +093069TEST(DecodePackageHeaderInfo, goodPath)
70{
Andrew Jeffery9c766792022-08-10 23:12:49 +093071 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +093072 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +103073 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +103074 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +093075
Andrew Jefferya3eba612025-03-06 17:11:20 +103076 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +103077 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
78 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
80 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
81 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x61, 0xe3, 0x64, 0x6e};
Andrew Jeffery9c766792022-08-10 23:12:49 +093082 pldm_package_header_information pkgHeader{};
83 variable_field packageVersion{};
84
85 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
86 packagerHeaderInfo.size(),
87 &pkgHeader, &packageVersion);
88
Andrew Jeffery150b06c2025-03-12 14:17:42 +103089 ASSERT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093090 EXPECT_EQ(true,
91 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
Andrew Jefferye038b962025-03-06 16:04:59 +103092 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.begin(),
93 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.end()));
94 EXPECT_EQ(pkgHeader.package_header_format_version,
95 PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0);
Andrew Jeffery150b06c2025-03-12 14:17:42 +103096 EXPECT_EQ(pkgHeader.package_header_size, packageHeaderSize);
Andrew Jeffery9c766792022-08-10 23:12:49 +093097 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
98 pkgHeader.package_release_date_time +
99 PLDM_TIMESTAMP104_SIZE,
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030100 testPackageReleaseDateTime.begin(),
101 testPackageReleaseDateTime.end()));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930102 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
103 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
104 EXPECT_EQ(pkgHeader.package_version_string_length,
105 packageVersionStr.size());
106 std::string packageVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930107 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930108 reinterpret_cast<const char*>(packageVersion.ptr),
109 packageVersion.length);
110 EXPECT_EQ(packageVersionString, packageVersionStr);
111}
112
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030113TEST(DecodePackageHeaderInfo, invalidArguments)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930114{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930115 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +1030116 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030117 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930118
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030119 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030120 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
121 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
123 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
124 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030125
126 pldm_package_header_information packageHeader{};
127 variable_field packageVersion{};
128 int rc = 0;
129
130 rc = decode_pldm_package_header_info(nullptr, packagerHeaderInfo.size(),
131 &packageHeader, &packageVersion);
132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
133
134 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
135 packagerHeaderInfo.size(), nullptr,
136 &packageVersion);
137 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
138
139 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
140 packagerHeaderInfo.size(),
141 &packageHeader, nullptr);
142 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
143}
144
145TEST(DecodePackageHeaderInfo, invalidPackageLengths)
146{
147 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
148 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030149 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030150
151 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030152 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
153 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
155 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
156 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030157
158 pldm_package_header_information packageHeader{};
159 variable_field packageVersion{};
160 int rc = 0;
161
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030162 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 0,
163 &packageHeader, &packageVersion);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030164 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030165
166 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 35,
167 &packageHeader, &packageVersion);
168 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
169
170 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 36,
171 &packageHeader, &packageVersion);
172 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
173
174 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
175 packagerHeaderInfo.size() - 1,
176 &packageHeader, &packageVersion);
177 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
178}
179
180TEST(DecodePackageHeaderInfo, unspecifiedPackageHeaderIdentifier)
181{
182 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
183 constexpr size_t packageHeaderSize =
184 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
185
186 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
187 0xff, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
188 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
189 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
190 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
191 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
192
193 pldm_package_header_information packageHeader{};
194 variable_field packageVersion{};
195 int rc = 0;
196
197 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
198 packagerHeaderInfo.size(),
199 &packageHeader, &packageVersion);
200 EXPECT_EQ(rc, PLDM_ERROR);
201}
202
203TEST(DecodePackageHeaderInfo, incongruentPackageHeaderFormatRevision)
204{
205 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
206 constexpr size_t packageHeaderSize =
207 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + 1 + packageVersionStr.size();
208
209 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
210 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
211 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x37, 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
213 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
214 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
215
216 pldm_package_header_information packageHeader{};
217 variable_field packageVersion{};
218 int rc = 0;
219
220 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
221 packagerHeaderInfo.size(),
222 &packageHeader, &packageVersion);
Andrew Jeffery2613c272025-03-12 14:15:41 +1030223 EXPECT_EQ(rc, PLDM_ERROR);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030224}
225
226TEST(DecodePackageHeaderInfo, invalidPackageVersionStringType)
227{
228 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
229 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030230 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030231
232 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030233 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
234 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
236 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
237 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930238
239 pldm_package_header_information packageHeader{};
240 variable_field packageVersion{};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030241 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930242
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030243 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
244 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930245 &packageHeader, &packageVersion);
246 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030247}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930248
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030249TEST(DecodePackageHeaderInfo, invalidPackageVersionStringLength)
250{
251 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
252 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030253 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930254
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030255 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030256 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
257 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
259 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
260 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030261
262 pldm_package_header_information packageHeader{};
263 variable_field packageVersion{};
264 int rc = 0;
265
266 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
267 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930268 &packageHeader, &packageVersion);
269 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030270}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930271
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030272TEST(DecodePackageHeaderInfo, corruptPackageVersionStringLength)
273{
274 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
275 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030276 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030277
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030278 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
279 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
280 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
282 0x00, 0x01, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
283 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030284
285 pldm_package_header_information packageHeader{};
286 variable_field packageVersion{};
287 int rc = 0;
288
289 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
290 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930291 &packageHeader, &packageVersion);
292 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030293}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930294
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030295TEST(DecodePackageHeaderInfo, invalidComponentBitmapBitLength)
296{
297 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
298 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030299 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030300
301 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030302 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
303 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x07,
305 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
306 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
307
308 pldm_package_header_information packageHeader{};
309 variable_field packageVersion{};
310 int rc = 0;
311
312 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
313 invalidPackagerHeaderInfo.size(),
314 &packageHeader, &packageVersion);
315 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
316}
317
318TEST(DecodePackageHeaderInfo, badChecksum)
319{
320 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
321 constexpr size_t packageHeaderSize =
322 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
323
324 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
325 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
326 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x10,
328 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
329 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030330
331 pldm_package_header_information packageHeader{};
332 variable_field packageVersion{};
333 int rc = 0;
334
335 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
336 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930337 &packageHeader, &packageVersion);
338 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
339}
340
341TEST(DecodeFirmwareDeviceIdRecord, goodPath)
342{
343 constexpr uint8_t descriptorCount = 1;
344 // Continue component updates after failure
345 constexpr std::bitset<32> deviceUpdateFlag{1};
346 constexpr uint16_t componentBitmapBitLength = 16;
347 // Applicable Components - 1,2,5,8,9
348 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
349 // ComponentImageSetVersionString
350 constexpr std::string_view imageSetVersionStr{"VersionString1"};
351 // Initial descriptor - UUID
352 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
353 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
354 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
355 constexpr uint16_t fwDevicePkgDataLen = 2;
356 // FirmwareDevicePackageData
357 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
358 0xcd};
359 // Size of the firmware device ID record
360 constexpr uint16_t recordLen =
361 sizeof(pldm_firmware_device_id_record) +
362 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
363 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
364 uuid.size() + fwDevicePkgData.size();
365 // Firmware device ID record
366 constexpr std::array<uint8_t, recordLen> record{
367 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
368 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
369 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
370 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
371 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
372
373 pldm_firmware_device_id_record deviceIdRecHeader{};
374 variable_field applicableComponents{};
375 variable_field outCompImageSetVersionStr{};
376 variable_field recordDescriptors{};
377 variable_field outFwDevicePkgData{};
378
379 auto rc = decode_firmware_device_id_record(
380 record.data(), record.size(), componentBitmapBitLength,
381 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
382 &recordDescriptors, &outFwDevicePkgData);
383
Andrew Jefferybacbbac2025-03-12 04:02:18 +0000384 ASSERT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930385 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
386 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
387 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
388 deviceUpdateFlag);
389 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
390 PLDM_STR_TYPE_ASCII);
391 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
392 imageSetVersionStr.size());
393 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
394
395 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
396 EXPECT_EQ(true,
397 std::equal(applicableComponents.ptr,
398 applicableComponents.ptr + applicableComponents.length,
399 applicableComponentsBitfield.begin(),
400 applicableComponentsBitfield.end()));
401
402 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
403 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930404 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930405 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
406 outCompImageSetVersionStr.length);
407 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
408
409 uint16_t descriptorType = 0;
410 uint16_t descriptorLen = 0;
411 variable_field descriptorData{};
412 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
413 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
414 recordDescriptors.length,
415 &descriptorType, &descriptorData);
416 EXPECT_EQ(rc, PLDM_SUCCESS);
417 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
418 sizeof(descriptorLen) +
419 descriptorData.length);
420 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
421 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
422 EXPECT_EQ(true, std::equal(descriptorData.ptr,
423 descriptorData.ptr + descriptorData.length,
424 uuid.begin(), uuid.end()));
425
426 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
427 EXPECT_EQ(true,
428 std::equal(outFwDevicePkgData.ptr,
429 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
430 fwDevicePkgData.begin(), fwDevicePkgData.end()));
431}
432
433TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
434{
435 constexpr uint8_t descriptorCount = 1;
436 // Continue component updates after failure
437 constexpr std::bitset<32> deviceUpdateFlag{1};
438 constexpr uint16_t componentBitmapBitLength = 8;
439 // Applicable Components - 1,2
440 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
441 // ComponentImageSetVersionString
442 constexpr std::string_view imageSetVersionStr{"VersionString1"};
443 // Initial descriptor - UUID
444 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
445 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
446 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
447 constexpr uint16_t fwDevicePkgDataLen = 0;
448
449 // Size of the firmware device ID record
450 constexpr uint16_t recordLen =
451 sizeof(pldm_firmware_device_id_record) +
452 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
453 imageSetVersionStr.size() +
454 sizeof(pldm_descriptor_tlv().descriptor_type) +
455 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
456 fwDevicePkgDataLen;
457 // Firmware device ID record
458 constexpr std::array<uint8_t, recordLen> record{
459 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
460 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
461 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
462 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
463
464 pldm_firmware_device_id_record deviceIdRecHeader{};
465 variable_field applicableComponents{};
466 variable_field outCompImageSetVersionStr{};
467 variable_field recordDescriptors{};
468 variable_field outFwDevicePkgData{};
469
470 auto rc = decode_firmware_device_id_record(
471 record.data(), record.size(), componentBitmapBitLength,
472 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
473 &recordDescriptors, &outFwDevicePkgData);
474
475 EXPECT_EQ(rc, PLDM_SUCCESS);
476 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
477 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
478 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
479 deviceUpdateFlag);
480 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
481 PLDM_STR_TYPE_ASCII);
482 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
483 imageSetVersionStr.size());
484 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
485
486 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
487 EXPECT_EQ(true,
488 std::equal(applicableComponents.ptr,
489 applicableComponents.ptr + applicableComponents.length,
490 applicableComponentsBitfield.begin(),
491 applicableComponentsBitfield.end()));
492
493 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
494 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930495 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930496 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
497 outCompImageSetVersionStr.length);
498 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
499
500 uint16_t descriptorType = 0;
501 uint16_t descriptorLen = 0;
502 variable_field descriptorData{};
503 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
504 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
505 recordDescriptors.length,
506 &descriptorType, &descriptorData);
507 EXPECT_EQ(rc, PLDM_SUCCESS);
508 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
509 sizeof(descriptorLen) +
510 descriptorData.length);
511 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
512 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
513 EXPECT_EQ(true, std::equal(descriptorData.ptr,
514 descriptorData.ptr + descriptorData.length,
515 uuid.begin(), uuid.end()));
516
517 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
518 EXPECT_EQ(outFwDevicePkgData.length, 0);
519}
520
521TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
522{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930523 // Invalid ComponentImageSetVersionStringType
Andrew Jeffery92c32362025-03-10 03:36:46 +0000524 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
525 0x00, 0x06, 0x0e, 0x00, 0x00};
526 constexpr uint16_t componentBitmapBitLength = 8;
527
528 pldm_firmware_device_id_record deviceIdRecHeader{};
529 variable_field outCompImageSetVersionStr{};
530 variable_field applicableComponents{};
531 variable_field outFwDevicePkgData{};
532 variable_field recordDescriptors{};
533 int rc = 0;
534
535 rc = decode_firmware_device_id_record(
536 nullptr, rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
537 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
538 &outFwDevicePkgData);
539 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
540
541 rc = decode_firmware_device_id_record(
542 rec.data(), rec.size(), componentBitmapBitLength, nullptr,
543 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
544 &outFwDevicePkgData);
545 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
546
547 rc = decode_firmware_device_id_record(
548 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
549 nullptr, &outCompImageSetVersionStr, &recordDescriptors,
550 &outFwDevicePkgData);
551 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
552
553 rc = decode_firmware_device_id_record(
554 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
555 &applicableComponents, nullptr, &recordDescriptors,
556 &outFwDevicePkgData);
557 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
558
559 rc = decode_firmware_device_id_record(
560 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
561 &applicableComponents, &outCompImageSetVersionStr, nullptr,
562 &outFwDevicePkgData);
563 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
564
565 rc = decode_firmware_device_id_record(
566 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
567 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
568 nullptr);
569 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
570
571 rc = decode_firmware_device_id_record(
572 rec.data(), rec.size() - 1, componentBitmapBitLength,
573 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
574 &recordDescriptors, &outFwDevicePkgData);
575 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
576
577 rc = decode_firmware_device_id_record(
578 rec.data(), rec.size(), componentBitmapBitLength + 1,
579 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
580 &recordDescriptors, &outFwDevicePkgData);
581 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
582
583 rc = decode_firmware_device_id_record(
584 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
585 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
586 &outFwDevicePkgData);
587 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
588}
589
590TEST(DecodeFirmwareDeviceIdRecord, invalidComponentImageSetVersionStringLength)
591{
592 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
593 0x00, 0x01, 0x00, 0x00, 0x00};
594 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930595
596 int rc = 0;
597 pldm_firmware_device_id_record deviceIdRecHeader{};
598 variable_field applicableComponents{};
599 variable_field outCompImageSetVersionStr{};
600 variable_field recordDescriptors{};
601 variable_field outFwDevicePkgData{};
602
603 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000604 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
605 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930606 &outFwDevicePkgData);
607 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000608}
609
610TEST(DecodeFirmwareDeviceIdRecord, shortBuffer)
611{
612 constexpr std::array<uint8_t, 11> rec{0x2e, 0x00, 0x01, 0x01, 0x00, 0x00,
613 0x00, 0x01, 0x0e, 0x00, 0x00};
614 constexpr uint16_t componentBitmapBitLength = 8;
615
616 pldm_firmware_device_id_record deviceIdRecHeader{};
617 variable_field outCompImageSetVersionStr{};
618 variable_field applicableComponents{};
619 variable_field outFwDevicePkgData{};
620 variable_field recordDescriptors{};
621 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930622
623 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000624 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
625 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
626 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930627 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000628}
629
630TEST(DecodeFirmwareDeviceIdRecord, recordLengthMismatch)
631{
632 constexpr std::array<uint8_t, 11> rec{0x15, 0x00, 0x01, 0x01, 0x00, 0x00,
633 0x00, 0x01, 0x0e, 0x02, 0x00};
634 constexpr uint16_t componentBitmapBitLength = 8;
635
636 pldm_firmware_device_id_record deviceIdRecHeader{};
637 variable_field outCompImageSetVersionStr{};
638 variable_field applicableComponents{};
639 variable_field outFwDevicePkgData{};
640 variable_field recordDescriptors{};
641 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930642
643 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000644 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
645 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
646 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930647 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000648}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930649
Andrew Jeffery92c32362025-03-10 03:36:46 +0000650TEST(DecodeFirmwareDeviceIdRecord, invalidFirmwareDevicePackageDataLength)
651{
652 constexpr std::array<uint8_t, 49> rec{
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800653 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
654 // FirmwareDevicePackageDataLength = 0xffff
655 0xff, 0xff,
656 //
657 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
658 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
659 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
660 0xab, 0xcd};
Andrew Jeffery92c32362025-03-10 03:36:46 +0000661 constexpr uint16_t componentBitmapBitLength = 8;
662
663 pldm_firmware_device_id_record deviceIdRecHeader{};
664 variable_field outCompImageSetVersionStr{};
665 variable_field applicableComponents{};
666 variable_field outFwDevicePkgData{};
667 variable_field recordDescriptors{};
668 int rc = 0;
669
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800670 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000671 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
672 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
673 &outFwDevicePkgData);
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800674 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930675}
676
677TEST(DecodeDescriptors, goodPath3Descriptors)
678{
679 // In the descriptor data there are 3 descriptor entries
680 // 1) IANA enterprise ID
681 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
682 0x0a, 0x0b, 0x0c, 0xd};
683 // 2) UUID
684 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
685 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
686 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
687 // 3) Vendor Defined
688 constexpr std::string_view vendorTitle{"OpenBMC"};
689 constexpr size_t vendorDescriptorLen = 2;
690 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
691 0x01, 0x02};
692
693 constexpr size_t vendorDefinedDescriptorLen =
694 sizeof(pldm_vendor_defined_descriptor_title_data()
695 .vendor_defined_descriptor_title_str_type) +
696 sizeof(pldm_vendor_defined_descriptor_title_data()
697 .vendor_defined_descriptor_title_str_len) +
698 vendorTitle.size() + vendorDescriptorData.size();
699
700 constexpr size_t descriptorsLength =
701 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
702 sizeof(pldm_descriptor_tlv().descriptor_length)) +
703 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
704
705 constexpr std::array<uint8_t, descriptorsLength> descriptors{
706 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
707 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600708 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930709 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
710
711 size_t descriptorCount = 1;
712 size_t descriptorsRemainingLength = descriptorsLength;
713 int rc = 0;
714
715 while (descriptorsRemainingLength && (descriptorCount <= 3))
716 {
717 uint16_t descriptorType = 0;
718 uint16_t descriptorLen = 0;
719 variable_field descriptorData{};
720
721 rc = decode_descriptor_type_length_value(
722 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
723 descriptorsRemainingLength, &descriptorType, &descriptorData);
724 EXPECT_EQ(rc, PLDM_SUCCESS);
725
726 if (descriptorCount == 1)
727 {
728 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
729 EXPECT_EQ(descriptorData.length,
730 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
731 EXPECT_EQ(true,
732 std::equal(descriptorData.ptr,
733 descriptorData.ptr + descriptorData.length,
734 iana.begin(), iana.end()));
735 }
736 else if (descriptorCount == 2)
737 {
738 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
739 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
740 EXPECT_EQ(true,
741 std::equal(descriptorData.ptr,
742 descriptorData.ptr + descriptorData.length,
743 uuid.begin(), uuid.end()));
744 }
745 else if (descriptorCount == 3)
746 {
747 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
748 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
749
750 uint8_t descriptorTitleStrType = 0;
751 variable_field descriptorTitleStr{};
752 variable_field vendorDefinedDescriptorData{};
753
754 rc = decode_vendor_defined_descriptor_value(
755 descriptorData.ptr, descriptorData.length,
756 &descriptorTitleStrType, &descriptorTitleStr,
757 &vendorDefinedDescriptorData);
758 EXPECT_EQ(rc, PLDM_SUCCESS);
759
760 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
761 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
762 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930763 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930764 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
765 descriptorTitleStr.length);
766 EXPECT_EQ(vendorTitleStr, vendorTitle);
767
768 EXPECT_EQ(vendorDefinedDescriptorData.length,
769 vendorDescriptorData.size());
770 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
771 vendorDefinedDescriptorData.ptr +
772 vendorDefinedDescriptorData.length,
773 vendorDescriptorData.begin(),
774 vendorDescriptorData.end()));
775 }
776
777 descriptorsRemainingLength -= sizeof(descriptorType) +
778 sizeof(descriptorLen) +
779 descriptorData.length;
780 descriptorCount++;
781 }
782}
783
784TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
785{
786 int rc = 0;
787 // IANA Enterprise ID descriptor length incorrect
788 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
789 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
790 uint16_t descriptorType = 0;
791 variable_field descriptorData{};
792
793 rc = decode_descriptor_type_length_value(nullptr,
794 invalidIANADescriptor1.size(),
795 &descriptorType, &descriptorData);
796 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
797
798 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
799 invalidIANADescriptor1.size(),
800 nullptr, &descriptorData);
801 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
802
803 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
804 invalidIANADescriptor1.size(),
805 &descriptorType, nullptr);
806 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
807
808 rc = decode_descriptor_type_length_value(
809 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
810 &descriptorType, &descriptorData);
811 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
812
813 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
814 invalidIANADescriptor1.size(),
815 &descriptorType, &descriptorData);
Andrew Jeffery779e9db2025-02-21 12:14:28 +1030816 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930817
818 // IANA Enterprise ID descriptor data less than length
819 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
820 0x0a, 0x0b, 0x0c};
821 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
822 invalidIANADescriptor2.size(),
823 &descriptorType, &descriptorData);
824 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
825}
826
827TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
828{
829 int rc = 0;
830 // VendorDefinedDescriptorTitleStringType is invalid
831 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
832 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
833 uint8_t descriptorStringType = 0;
834 variable_field descriptorTitleStr{};
835 variable_field vendorDefinedDescriptorData{};
836
837 rc = decode_vendor_defined_descriptor_value(
838 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
839 &descriptorTitleStr, &vendorDefinedDescriptorData);
840 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
841
842 rc = decode_vendor_defined_descriptor_value(
843 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
844 &descriptorStringType, &descriptorTitleStr,
845 &vendorDefinedDescriptorData);
846 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
847
848 rc = decode_vendor_defined_descriptor_value(
849 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
850 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
851 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
852
853 rc = decode_vendor_defined_descriptor_value(
854 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
855 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
856 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
857
858 rc = decode_vendor_defined_descriptor_value(
859 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
860 &descriptorStringType, &descriptorTitleStr, nullptr);
861 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
862
863 rc = decode_vendor_defined_descriptor_value(
864 invalidVendorDescriptor1.data(),
865 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
866 &descriptorStringType, &descriptorTitleStr,
867 &vendorDefinedDescriptorData);
868 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
869
870 rc = decode_vendor_defined_descriptor_value(
871 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
872 &descriptorStringType, &descriptorTitleStr,
873 &vendorDefinedDescriptorData);
874 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
875
876 // VendorDefinedDescriptorTitleStringLength is 0
877 std::array<uint8_t, 9> invalidVendorDescriptor2{
878 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
879 rc = decode_vendor_defined_descriptor_value(
880 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
881 &descriptorStringType, &descriptorTitleStr,
882 &vendorDefinedDescriptorData);
883 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
884
885 // VendorDefinedDescriptorData not present in the data
886 std::array<uint8_t, 9> invalidVendorDescriptor3{
887 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
888 rc = decode_vendor_defined_descriptor_value(
889 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
890 &descriptorStringType, &descriptorTitleStr,
891 &vendorDefinedDescriptorData);
892 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
893}
894
895TEST(DecodeComponentImageInfo, goodPath)
896{
897 // Firmware
898 constexpr uint16_t compClassification = 16;
899 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600900 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930901 // Force update
902 constexpr std::bitset<16> compOptions{1};
903 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
904 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
905 // Random ComponentLocationOffset
906 constexpr uint32_t compLocOffset = 357;
907 // Random ComponentSize
908 constexpr uint32_t compSize = 27;
909 // ComponentVersionString
910 constexpr std::string_view compVersionStr{"VersionString1"};
911 constexpr size_t compImageInfoSize =
912 sizeof(pldm_component_image_information) + compVersionStr.size();
913
914 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
915 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
916 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
917 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
918 pldm_component_image_information outCompImageInfo{};
919 variable_field outCompVersionStr{};
920
921 auto rc =
922 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
923 &outCompImageInfo, &outCompVersionStr);
924
925 EXPECT_EQ(rc, PLDM_SUCCESS);
926 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
927 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
928 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
929 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
930 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
931 reqCompActivationMethod);
932 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
933 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
934 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
935 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
936 compVersionStr.size());
937
938 EXPECT_EQ(outCompVersionStr.length,
939 outCompImageInfo.comp_version_string_length);
940 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930941 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930942 reinterpret_cast<const char*>(outCompVersionStr.ptr),
943 outCompVersionStr.length);
944 EXPECT_EQ(componentVersionString, compVersionStr);
945}
946
947TEST(DecodeComponentImageInfo, errorPaths)
948{
949 int rc = 0;
950 // ComponentVersionString
951 constexpr std::string_view compVersionStr{"VersionString1"};
952 constexpr size_t compImageInfoSize =
953 sizeof(pldm_component_image_information) + compVersionStr.size();
954 // Invalid ComponentVersionStringType - 0x06
955 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
956 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
957 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
958 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
959 pldm_component_image_information outCompImageInfo{};
960 variable_field outCompVersionStr{};
961
962 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
963 &outCompImageInfo, &outCompVersionStr);
964 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
965
966 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
967 invalidCompImageInfo1.size(), nullptr,
968 &outCompVersionStr);
969 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
970
971 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
972 invalidCompImageInfo1.size(),
973 &outCompImageInfo, nullptr);
974 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
975
976 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
977 sizeof(pldm_component_image_information) -
978 1,
979 &outCompImageInfo, &outCompVersionStr);
980 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
981
982 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
983 invalidCompImageInfo1.size(),
984 &outCompImageInfo, &outCompVersionStr);
985 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
986
987 // Invalid ComponentVersionStringLength - 0x00
988 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
989 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
990 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
991 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
992 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
993 invalidCompImageInfo2.size(),
994 &outCompImageInfo, &outCompVersionStr);
995 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
996
997 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600998 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +0930999 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
1000 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
1001 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1002 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1003
1004 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
1005 invalidCompImageInfo3.size() - 1,
1006 &outCompImageInfo, &outCompVersionStr);
1007 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1008
1009 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
1010 invalidCompImageInfo3.size(),
1011 &outCompImageInfo, &outCompVersionStr);
1012 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1013
1014 // Invalid ComponentLocationOffset - 0
1015 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
1016 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1017 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1018 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1019 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
1020 invalidCompImageInfo4.size(),
1021 &outCompImageInfo, &outCompVersionStr);
1022 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1023
1024 // Invalid ComponentSize - 0
1025 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
1026 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1027 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1028 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1029 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
1030 invalidCompImageInfo5.size(),
1031 &outCompImageInfo, &outCompVersionStr);
1032 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1033}
1034
1035TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
1036{
1037 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301038 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301039 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1040
1041 uint8_t instanceId = 0x01;
1042
1043 auto rc = encode_query_device_identifiers_req(
1044 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
1045 EXPECT_EQ(rc, PLDM_SUCCESS);
1046 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1047 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1048 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1049 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
1050}
1051
1052TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
1053{
1054 // descriptorDataLen is not fixed here taking it as 6
1055 constexpr uint8_t descriptorDataLen = 6;
1056 std::array<uint8_t, hdrSize +
1057 sizeof(struct pldm_query_device_identifiers_resp) +
1058 descriptorDataLen>
1059 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301060 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301061 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
1062 responseMsg.data() + hdrSize);
1063
1064 inResp->completion_code = PLDM_SUCCESS;
1065 inResp->device_identifiers_len = htole32(descriptorDataLen);
1066 inResp->descriptor_count = 1;
1067
1068 // filling descriptor data
1069 std::fill_n(responseMsg.data() + hdrSize +
1070 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001071 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301072
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301073 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301074 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1075 uint8_t completionCode = PLDM_SUCCESS;
1076 uint32_t deviceIdentifiersLen = 0;
1077 uint8_t descriptorCount = 0;
1078 uint8_t* outDescriptorData = nullptr;
1079
1080 auto rc = decode_query_device_identifiers_resp(
1081 response, responseMsg.size() - hdrSize, &completionCode,
1082 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
1083
1084 EXPECT_EQ(rc, PLDM_SUCCESS);
1085 EXPECT_EQ(completionCode, PLDM_SUCCESS);
1086 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
1087 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
1088 EXPECT_EQ(true,
1089 std::equal(outDescriptorData,
1090 outDescriptorData + deviceIdentifiersLen,
1091 responseMsg.begin() + hdrSize +
1092 sizeof(struct pldm_query_device_identifiers_resp),
1093 responseMsg.end()));
1094}
1095
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001096#ifdef LIBPLDM_API_TESTING
1097TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
1098{
1099 int rc;
1100 PLDM_MSG_DEFINE_P(enc, 1000);
1101 size_t enc_payload_len = 1000;
1102 pldm_descriptor check_desc[] = {
1103 {
1104 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
1105 .descriptor_length = 4,
1106 .descriptor_data = "a123",
1107 },
1108 {
1109 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
1110 .descriptor_length = 3,
1111 .descriptor_data = "987",
1112 },
1113 };
1114 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
1115 enc, &enc_payload_len);
1116 EXPECT_EQ(rc, 0);
1117 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
1118 ElementsAreArray<uint8_t>({
1119 // completion code
1120 0x00,
1121 // device identifiers length = 15
1122 0x0f,
1123 0x00,
1124 0x00,
1125 0x00,
1126 // descriptor count
1127 0x02,
1128 // desc 0
1129 0x01,
1130 0x00,
1131 0x04,
1132 0x00,
1133 0x61,
1134 0x31,
1135 0x32,
1136 0x33,
1137 // desc 1
1138 0xff,
1139 0xff,
1140 0x03,
1141 0x00,
1142 0x39,
1143 0x38,
1144 0x37,
1145 }));
1146
1147 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
1148}
1149#endif
1150
Andrew Jeffery9c766792022-08-10 23:12:49 +09301151TEST(GetFirmwareParameters, goodPathEncodeRequest)
1152{
1153 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301154 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301155 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1156 uint8_t instanceId = 0x01;
1157
1158 auto rc = encode_get_firmware_parameters_req(
1159 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
1160 EXPECT_EQ(rc, PLDM_SUCCESS);
1161 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1162 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1163 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1164 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
1165}
1166
1167TEST(GetFirmwareParameters, decodeResponse)
1168{
1169 // CapabilitiesDuringUpdate of the firmware device
1170 // Firmware device downgrade restrictions [Bit position 8] &
1171 // Firmware Device Partial Updates [Bit position 3]
1172 constexpr std::bitset<32> fdCapabilities{0x00000104};
1173 constexpr uint16_t compCount = 1;
1174 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1175 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1176
1177 // constexpr uint16_t compClassification = 16;
1178 // constexpr uint16_t compIdentifier = 300;
1179 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001180 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301181 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
1182 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1183 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
1184 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
1185 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
1186 constexpr std::string_view activeCompVersion{"VersionString3"};
1187 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +09301188
1189 constexpr size_t compParamTableSize =
1190 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
1191 pendingCompVersion.size();
1192
1193 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001194 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301195 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1196 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
1197 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
1198 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1199 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1200
1201 constexpr size_t getFwParamsPayloadLen =
1202 sizeof(pldm_get_firmware_parameters_resp) +
1203 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1204 compParamTableSize;
1205
1206 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1207 getFwParamsResponse{
1208 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1209 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1210 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1211 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001212 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301213 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1214 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1215 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1216 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1217 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1218
1219 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301220 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301221 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1222 pldm_get_firmware_parameters_resp outResp{};
1223 variable_field outActiveCompImageSetVersion{};
1224 variable_field outPendingCompImageSetVersion{};
1225 variable_field outCompParameterTable{};
1226
1227 auto rc = decode_get_firmware_parameters_resp(
1228 responseMsg, getFwParamsPayloadLen, &outResp,
1229 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1230 &outCompParameterTable);
1231
1232 EXPECT_EQ(rc, PLDM_SUCCESS);
1233 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1234 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1235 EXPECT_EQ(outResp.comp_count, compCount);
1236 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1237 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1238 activeCompImageSetVersion.size());
1239 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1240 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1241 pendingCompImageSetVersion.size());
1242 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301243 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301244 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1245 outActiveCompImageSetVersion.length);
1246 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1247 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301248 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301249 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1250 outPendingCompImageSetVersion.length);
1251 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1252 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1253 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1254 outCompParameterTable.ptr +
1255 outCompParameterTable.length,
1256 compParamTable.begin(), compParamTable.end()));
1257}
1258
1259TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1260{
1261 // CapabilitiesDuringUpdate of the firmware device
1262 // FD Host Functionality during Firmware Update [Bit position 2] &
1263 // Component Update Failure Retry Capability [Bit position 1]
1264 constexpr std::bitset<32> fdCapabilities{0x06};
1265 constexpr uint16_t compCount = 0;
1266 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1267 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1268
1269 constexpr size_t getFwParamsPayloadLen =
1270 sizeof(pldm_get_firmware_parameters_resp) +
1271 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1272
1273 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1274 getFwParamsResponse{
1275 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1276 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1277 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1278 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
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, getFwParamsPayloadLen, &outResp,
1290 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1291 &outCompParameterTable);
1292
1293 EXPECT_EQ(rc, PLDM_SUCCESS);
1294 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1295 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1296 EXPECT_EQ(outResp.comp_count, compCount);
1297 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1298 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1299 activeCompImageSetVersion.size());
1300 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1301 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1302 pendingCompImageSetVersion.size());
1303 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301304 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301305 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1306 outActiveCompImageSetVersion.length);
1307 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1308 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301309 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301310 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1311 outPendingCompImageSetVersion.length);
1312 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1313 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1314 EXPECT_EQ(outCompParameterTable.length, 0);
1315}
1316
1317TEST(GetFirmwareParameters,
1318 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1319{
1320 // CapabilitiesDuringUpdate of the firmware device
1321 // FD Host Functionality during Firmware Update [Bit position 2] &
1322 // Component Update Failure Retry Capability [Bit position 1]
1323 constexpr std::bitset<32> fdCapabilities{0x06};
1324 constexpr uint16_t compCount = 0;
1325 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1326
1327 constexpr size_t getFwParamsPayloadLen =
1328 sizeof(pldm_get_firmware_parameters_resp) +
1329 activeCompImageSetVersion.size();
1330
1331 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1332 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1333 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1334 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1335 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1336
1337 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301338 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301339 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1340 pldm_get_firmware_parameters_resp outResp{};
1341 variable_field outActiveCompImageSetVersion{};
1342 variable_field outPendingCompImageSetVersion{};
1343 variable_field outCompParameterTable{};
1344
1345 auto rc = decode_get_firmware_parameters_resp(
1346 responseMsg, getFwParamsPayloadLen, &outResp,
1347 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1348 &outCompParameterTable);
1349
1350 EXPECT_EQ(rc, PLDM_SUCCESS);
1351 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1352 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1353 EXPECT_EQ(outResp.comp_count, compCount);
1354 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1355 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1356 activeCompImageSetVersion.size());
1357 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1358 PLDM_STR_TYPE_UNKNOWN);
1359 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1360 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301361 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301362 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1363 outActiveCompImageSetVersion.length);
1364 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1365 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1366 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1367 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1368 EXPECT_EQ(outCompParameterTable.length, 0);
1369}
1370
1371TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1372{
1373 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1374 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1375
1376 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301377 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301378 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1379 pldm_get_firmware_parameters_resp outResp{};
1380 variable_field outActiveCompImageSetVersion{};
1381 variable_field outPendingCompImageSetVersion{};
1382 variable_field outCompParameterTable{};
1383
1384 auto rc = decode_get_firmware_parameters_resp(
1385 responseMsg, getFwParamsResponse.size(), &outResp,
1386 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1387 &outCompParameterTable);
1388
1389 EXPECT_EQ(rc, PLDM_SUCCESS);
1390 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1391}
1392
1393TEST(GetFirmwareParameters, errorPathdecodeResponse)
1394{
1395 int rc = 0;
1396 // Invalid ActiveComponentImageSetVersionStringType
1397 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1399 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1400
1401 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301402 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301403 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1404 pldm_get_firmware_parameters_resp outResp{};
1405 variable_field outActiveCompImageSetVersion{};
1406 variable_field outPendingCompImageSetVersion{};
1407 variable_field outCompParameterTable{};
1408
1409 rc = decode_get_firmware_parameters_resp(
1410 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1411 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1412 &outCompParameterTable);
1413 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1414
1415 rc = decode_get_firmware_parameters_resp(
1416 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1417 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1418 &outCompParameterTable);
1419 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1420
1421 rc = decode_get_firmware_parameters_resp(
1422 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1423 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1424 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1425
1426 rc = decode_get_firmware_parameters_resp(
1427 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1428 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1429 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1430
1431 rc = decode_get_firmware_parameters_resp(
1432 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1433 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1434 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1435
1436 rc = decode_get_firmware_parameters_resp(
1437 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1438 &outPendingCompImageSetVersion, &outCompParameterTable);
1439 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1440
1441 rc = decode_get_firmware_parameters_resp(
1442 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1443 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1444 &outCompParameterTable);
1445 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1446
1447 rc = decode_get_firmware_parameters_resp(
1448 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1449 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1450 &outCompParameterTable);
1451 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1452
1453 // Invalid ActiveComponentImageSetVersionStringLength
1454 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1456 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1457 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301458 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301459 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1460 rc = decode_get_firmware_parameters_resp(
1461 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1462 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1463 &outCompParameterTable);
1464 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1465
1466 // Invalid PendingComponentImageSetVersionStringType &
1467 // PendingComponentImageSetVersionStringLength
1468 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1469 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1470 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1471 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301472 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301473 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1474 rc = decode_get_firmware_parameters_resp(
1475 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1476 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1477 &outCompParameterTable);
1478 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1479
1480 // Invalid PendingComponentImageSetVersionStringType &
1481 // PendingComponentImageSetVersionStringLength
1482 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1483 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1484 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1485 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301486 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301487 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1488 rc = decode_get_firmware_parameters_resp(
1489 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1490 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1491 &outCompParameterTable);
1492 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1493
1494 // Total payload length less than expected
1495 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1496 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1497 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1498 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301499 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301500 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1501 rc = decode_get_firmware_parameters_resp(
1502 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1503 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1504 &outCompParameterTable);
1505 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1506}
1507
1508TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1509{
1510 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001511 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301512 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001513 constexpr uint16_t compIdentifier = 0x0c0d;
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001514 constexpr uint16_t compClassificationIndex = 0xf;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301515 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001516 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301517 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001518 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301519 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001520 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301521
1522 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1523 constexpr uint8_t activeCompVerStrLen = 8;
1524 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1525 constexpr uint8_t pendingCompVerStrLen = 8;
1526 constexpr size_t entryLength =
1527 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1528 pendingCompVerStrLen;
1529 std::array<uint8_t, entryLength> entry{};
1530
1531 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301532 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301533 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1534
1535 inEntry->comp_classification = htole16(compClassification);
1536 inEntry->comp_identifier = htole16(compIdentifier);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001537 inEntry->comp_classification_index = compClassificationIndex;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301538 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1539 inEntry->active_comp_ver_str_type = 1;
1540 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1541 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001542 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301543 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1544 inEntry->pending_comp_ver_str_type = 1;
1545 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1546 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001547 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301548 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1549 inEntry->capabilities_during_update.value =
1550 htole32(capabilitiesDuringUpdate);
1551 constexpr auto activeCompVerStrPos =
1552 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001553 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301554 constexpr auto pendingCompVerStrPos =
1555 activeCompVerStrPos + activeCompVerStrLen;
1556 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001557 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301558
1559 struct pldm_component_parameter_entry outEntry;
1560 struct variable_field outActiveCompVerStr;
1561 struct variable_field outPendingCompVerStr;
1562
1563 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1564 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1565 &outPendingCompVerStr);
1566
1567 EXPECT_EQ(rc, PLDM_SUCCESS);
1568
1569 EXPECT_EQ(outEntry.comp_classification, compClassification);
1570 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1571 EXPECT_EQ(inEntry->comp_classification_index,
1572 outEntry.comp_classification_index);
1573 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1574 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1575 outEntry.active_comp_ver_str_type);
1576 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1577 outEntry.active_comp_ver_str_len);
1578 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1579 outEntry.active_comp_release_date,
1580 sizeof(inEntry->active_comp_release_date)));
1581 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1582 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1583 outEntry.pending_comp_ver_str_type);
1584 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1585 outEntry.pending_comp_ver_str_len);
1586 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1587 outEntry.pending_comp_release_date,
1588 sizeof(inEntry->pending_comp_release_date)));
1589 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1590 EXPECT_EQ(outEntry.capabilities_during_update.value,
1591 capabilitiesDuringUpdate);
1592
1593 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1594 entry.data() + activeCompVerStrPos,
1595 outActiveCompVerStr.length));
1596 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1597 entry.data() + pendingCompVerStrPos,
1598 outPendingCompVerStr.length));
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001599
1600#ifdef LIBPLDM_API_TESTING
1601 /* Check the roundtrip matches */
1602 std::vector<uint8_t> enc_data(1000);
1603 size_t enc_payload_len = enc_data.size();
1604 struct pldm_component_parameter_entry_full entryFull = {
1605 .comp_classification = compClassification,
1606 .comp_identifier = compIdentifier,
1607 .comp_classification_index = compClassificationIndex,
1608 .active_ver =
1609 {
1610 .comparison_stamp = 0x12345678,
1611 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1612 .str_len = activeCompVerStrLen,
1613 .str_data = {}},
1614 .date = {},
1615 },
1616 .pending_ver =
1617 {
1618 .comparison_stamp = 0x12345678,
1619 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1620 .str_len = pendingCompVerStrLen,
1621 .str_data = {}},
1622 .date = {},
1623 },
1624 .comp_activation_methods = inEntry->comp_activation_methods,
1625 .capabilities_during_update = inEntry->capabilities_during_update,
1626 };
1627 // Fill strings
1628 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1629 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1630 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1631 0xff);
1632 std::fill_n(entryFull.pending_ver.date,
1633 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1634
1635 rc = encode_get_firmware_parameters_resp_comp_entry(
1636 &entryFull, enc_data.data(), &enc_payload_len);
1637 EXPECT_EQ(rc, PLDM_SUCCESS);
1638 EXPECT_EQ(enc_payload_len, entryLength);
1639 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1640#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301641}
1642
Chris Wang4c1f2c72024-03-21 17:09:44 +08001643TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1644{
1645 constexpr uint8_t instanceId = 1;
1646 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301647 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001648 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1649
1650 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1651
Unive Tien71e935c2024-11-25 17:21:43 +08001652 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001653 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1654 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1655 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1656 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1657}
1658
1659TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1660{
1661 constexpr uint8_t instanceId = 1;
1662
1663 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1664
Unive Tien71e935c2024-11-25 17:21:43 +08001665 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001666}
1667
1668TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1669{
1670 uint8_t completion_code_resp = PLDM_SUCCESS;
1671 uint8_t downstream_device_update_supported_resp =
1672 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1673 uint16_t number_of_downstream_devices_resp = 1;
1674 uint16_t max_number_of_downstream_devices_resp = 1;
1675 /** Capabilities of updating downstream devices
1676 * FDP supports downstream devices dynamically attached [Bit position 0] &
1677 * FDP supports downstream devices dynamically removed [Bit position 1]
1678 */
1679 bitfield32_t capabilities_resp = {.value = 0x0002};
1680 int rc;
1681
1682 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1683 responseMsg{};
1684
Andrew Jefferya1896962025-03-03 21:41:25 +10301685 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301686 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1687 responseMsg.size() - hdrSize);
1688 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001689
1690 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1691 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1692 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1693 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1694 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301695 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001696
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301697 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001698 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1699 struct pldm_query_downstream_devices_resp resp_data;
1700
1701 rc = decode_query_downstream_devices_resp(
1702 response, responseMsg.size() - hdrSize, &resp_data);
1703
Unive Tien71e935c2024-11-25 17:21:43 +08001704 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001705 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1706 EXPECT_EQ(resp_data.downstream_device_update_supported,
1707 downstream_device_update_supported_resp);
1708 EXPECT_EQ(resp_data.number_of_downstream_devices,
1709 number_of_downstream_devices_resp);
1710 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1711 max_number_of_downstream_devices_resp);
1712 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1713}
1714
1715TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1716{
1717 uint8_t completion_code_resp = PLDM_SUCCESS;
1718 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1719 uint16_t number_of_downstream_devices_resp = 1;
1720 uint16_t max_number_of_downstream_devices_resp = 1;
1721 /** Capabilities of updating downstream devices
1722 * FDP supports downstream devices dynamically attached [Bit position 0] &
1723 * FDP supports downstream devices dynamically removed [Bit position 1]
1724 */
1725 bitfield32_t capabilities_resp = {.value = 0x0002};
1726 int rc;
1727
1728 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1729 responseMsg{};
1730
Andrew Jefferya1896962025-03-03 21:41:25 +10301731 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301732 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1733 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301734 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001735 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1736 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1737 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1738 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1739 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301740 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001741
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301742 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001743 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1744 struct pldm_query_downstream_devices_resp resp_data;
1745
1746 rc = decode_query_downstream_devices_resp(
1747 response, responseMsg.size() - hdrSize, &resp_data);
1748
Unive Tien71e935c2024-11-25 17:21:43 +08001749 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001750}
1751
1752TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1753{
1754 uint8_t completion_code_resp = PLDM_SUCCESS;
1755 uint8_t downstream_device_update_supported_resp =
1756 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1757 uint16_t number_of_downstream_devices_resp = 1;
1758 uint16_t max_number_of_downstream_devices_resp = 1;
1759 /** Capabilities of updating downstream devices
1760 * FDP supports downstream devices dynamically attached [Bit position 0] &
1761 * FDP supports downstream devices dynamically removed [Bit position 1]
1762 */
1763 bitfield32_t capabilities_resp = {.value = 0x0002};
1764 int rc;
1765
1766 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1767 2 /* Inject error length*/>
1768 responseMsg{};
1769
Andrew Jefferya1896962025-03-03 21:41:25 +10301770 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301771 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1772 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301773 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001774
1775 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1776 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1777 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1778 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1779 // Inject error value
1780 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301781 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001782
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301783 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001784 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1785 struct pldm_query_downstream_devices_resp resp_data;
1786
1787 rc = decode_query_downstream_devices_resp(
1788 response, responseMsg.size() - hdrSize, &resp_data);
1789
Unive Tien71e935c2024-11-25 17:21:43 +08001790 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001791}
1792
Chris Wang458475a2024-03-26 17:59:19 +08001793TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1794{
1795 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301796 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1797 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001798 constexpr pldm_query_downstream_identifiers_req params_req{
1799 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001800
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001801 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1802 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001803 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301804 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1805 ElementsAreArray<uint8_t>(
1806 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001807}
1808
1809TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1810{
1811 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001812 constexpr pldm_query_downstream_identifiers_req params_req{
1813 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1814 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1815 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001816 constexpr size_t payload_length =
1817 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1818 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301819 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001820 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1821
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001822 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1823 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001824 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001825
1826 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001827 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001828 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001829
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001830 rc = encode_query_downstream_identifiers_req(
1831 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001832 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001833}
1834
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301835TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001836{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301837 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1838 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1839 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1840 constexpr uint32_t downstream_devices_length_resp = 0;
1841 constexpr uint16_t number_of_downstream_devices_resp = 0;
1842
1843 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1844 struct pldm_query_downstream_identifiers_resp resp_data = {};
1845 struct pldm_downstream_device_iter devs;
Andrew Jefferya1896962025-03-03 21:41:25 +10301846 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301847 int rc = 0;
1848
1849 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1850 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1851 ASSERT_EQ(rc, 0);
1852
1853 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1854 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1855 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1856 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1857 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1858
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301859 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301860
1861 rc = decode_query_downstream_identifiers_resp(
1862 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1863 &devs);
1864
Unive Tien71e935c2024-11-25 17:21:43 +08001865 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301866 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1867 EXPECT_EQ(resp_data.next_data_transfer_handle,
1868 next_data_transfer_handle_resp);
1869 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1870 EXPECT_EQ(resp_data.downstream_devices_length,
1871 downstream_devices_length_resp);
1872 EXPECT_EQ(resp_data.number_of_downstream_devices,
1873 number_of_downstream_devices_resp);
1874}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301875
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301876TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1877{
1878 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1879 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1880 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1881 constexpr uint32_t downstream_devices_length_resp = 0;
1882 constexpr uint16_t number_of_downstream_devices_resp = 1;
1883
1884 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1885 struct pldm_query_downstream_identifiers_resp resp = {};
1886 struct pldm_downstream_device_iter devs;
1887 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301888 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301889 int rc = 0;
1890
1891 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1892 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1893 ASSERT_EQ(rc, 0);
1894
1895 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1896 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1897 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1898 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1899 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1900
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301901 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301902
1903 rc = decode_query_downstream_identifiers_resp(
1904 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001905 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301906
1907 foreach_pldm_downstream_device(devs, dev, rc)
1908 {
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10301909 FAIL();
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301910 }
1911 ASSERT_NE(rc, 0);
1912}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301913
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301914TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1915{
1916 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301917 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001918 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1919 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1920 const uint32_t downstream_devices_length_resp =
1921 htole32(downstreamDevicesLen);
1922 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301923 constexpr size_t payloadLen =
1924 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001925
Andrew Jefferydec237b2024-11-08 14:33:45 +10301926 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301927 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301928 struct pldm_downstream_device_iter devs;
1929 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301930 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301931 int rc = 0;
1932
1933 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1934 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001935
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301936 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001937 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1938 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1939 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1940 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1941
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301942 /* Downstream device */
1943 pldm_msgbuf_insert_uint16(buf, 1);
1944 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001945
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301946 /* Device descriptor */
1947 pldm_msgbuf_insert_uint16(buf, 1);
1948 pldm_msgbuf_insert_uint16(buf, 4);
1949 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001950
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301951 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301952
1953 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1954 &resp_data, &devs);
1955
Unive Tien71e935c2024-11-25 17:21:43 +08001956 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301957 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001958 EXPECT_EQ(resp_data.next_data_transfer_handle,
1959 next_data_transfer_handle_resp);
1960 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1961 EXPECT_EQ(resp_data.downstream_devices_length,
1962 downstream_devices_length_resp);
1963 EXPECT_EQ(resp_data.number_of_downstream_devices,
1964 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301965
1966 foreach_pldm_downstream_device(devs, dev, rc)
1967 {
1968 struct pldm_descriptor desc;
1969
1970 EXPECT_EQ(dev.downstream_device_index, 1);
1971 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1972
1973 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1974 {
1975 static const uint32_t dmtf = htole32(412);
1976 EXPECT_EQ(desc.descriptor_type, 1);
1977 EXPECT_EQ(desc.descriptor_length, 4);
1978 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1979 }
1980 ASSERT_EQ(rc, 0);
1981 }
1982 ASSERT_EQ(rc, 0);
1983}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301984
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301985constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1986constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1987const uint32_t iana_pen_openbmc = htole16(49871u);
1988const uint32_t iana_pen_dmtf = htole16(412u);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301989
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301990TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1991{
1992 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1993 {0, 1},
1994 {1, 1},
1995 }};
1996
1997 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1998 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1999 &iana_pen_dmtf},
2000 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2001 &iana_pen_openbmc},
2002 }};
2003
2004 constexpr uint32_t downstream_devices_len = 22;
2005 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2006 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2007 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2008 const uint32_t downstream_devices_length_resp =
2009 htole32(downstream_devices_len);
2010 constexpr uint16_t number_of_downstream_devices_resp = 2;
2011 constexpr size_t payloadLen =
2012 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2013
Patrick Williamsf37edd72024-12-18 11:22:58 -05002014 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302015 PLDM_MSG_DEFINE_P(response, payloadLen);
2016 struct pldm_downstream_device_iter devs;
2017 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302018 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302019 int rc = 0;
2020
2021 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2022 ASSERT_EQ(rc, 0);
2023
2024 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2025 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2026 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2027 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2028 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2029
2030 /* Downstream device */
2031 pldm_msgbuf_insert_uint16(buf, 0);
2032 pldm_msgbuf_insert_uint8(buf, 1);
2033
2034 /* Device descriptor */
2035 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2036 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2037 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2038
2039 /* Downstream device */
2040 pldm_msgbuf_insert_uint16(buf, 1);
2041 pldm_msgbuf_insert_uint8(buf, 1);
2042
2043 /* Device descriptor */
2044 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2045 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2046 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2047
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302048 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302049
2050 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2051 &resp_data, &devs);
2052
Unive Tien71e935c2024-11-25 17:21:43 +08002053 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302054 EXPECT_EQ(resp_data.number_of_downstream_devices,
2055 number_of_downstream_devices_resp);
2056
2057 size_t devIndex = 0;
2058 size_t descIndex = 0;
2059 foreach_pldm_downstream_device(devs, dev, rc)
2060 {
2061 struct pldm_descriptor desc;
2062
2063 ASSERT_LT(devIndex, expected_devices.size());
2064
2065 const struct pldm_downstream_device* expectedDev =
2066 &expected_devices[devIndex];
2067
2068 EXPECT_EQ(dev.downstream_device_index,
2069 expectedDev->downstream_device_index);
2070 EXPECT_EQ(dev.downstream_descriptor_count,
2071 expectedDev->downstream_descriptor_count);
2072
2073 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2074 {
2075 ASSERT_LT(descIndex, expected_descriptors.size());
2076
2077 const struct pldm_descriptor* expectedDesc =
2078 &expected_descriptors[descIndex];
2079
2080 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2081 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2082 EXPECT_EQ(memcmp(desc.descriptor_data,
2083 expectedDesc->descriptor_data,
2084 expectedDesc->descriptor_length),
2085 0);
2086
2087 descIndex++;
2088 }
2089 ASSERT_EQ(rc, 0);
2090 EXPECT_EQ(descIndex, 1 * devIndex + 1);
2091
2092 devIndex++;
2093 }
2094 ASSERT_EQ(rc, 0);
2095 EXPECT_EQ(devIndex, 2);
2096}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302097
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302098TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
2099{
2100 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2101 {0, 2},
2102 {1, 1},
2103 }};
2104
2105 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2106 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2107 &iana_pen_dmtf},
2108 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2109 &iana_pen_openbmc},
2110 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2111 &iana_pen_dmtf},
2112 }};
2113
2114 constexpr uint32_t downstream_devices_len = 30;
2115 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2116 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2117 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2118 const uint32_t downstream_devices_length_resp =
2119 htole32(downstream_devices_len);
2120 constexpr uint16_t number_of_downstream_devices_resp = 2;
2121 constexpr size_t payloadLen =
2122 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2123
Patrick Williamsf37edd72024-12-18 11:22:58 -05002124 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302125 PLDM_MSG_DEFINE_P(response, payloadLen);
2126 struct pldm_downstream_device_iter devs;
2127 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302128 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302129 int rc = 0;
2130
2131 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2132 ASSERT_EQ(rc, 0);
2133
2134 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2135 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2136 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2137 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2138 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2139
2140 /* Downstream device */
2141 pldm_msgbuf_insert_uint16(buf, 0);
2142 pldm_msgbuf_insert_uint8(buf, 2);
2143
2144 /* Device descriptor */
2145 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2146 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2147 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2148
2149 /* Device descriptor */
2150 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2151 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2152 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2153
2154 /* Downstream device */
2155 pldm_msgbuf_insert_uint16(buf, 1);
2156 pldm_msgbuf_insert_uint8(buf, 1);
2157
2158 /* Device descriptor */
2159 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2160 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2161 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2162
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302163 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302164
2165 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2166 &resp_data, &devs);
2167
Unive Tien71e935c2024-11-25 17:21:43 +08002168 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302169 EXPECT_EQ(resp_data.number_of_downstream_devices,
2170 number_of_downstream_devices_resp);
2171
2172 size_t devIndex = 0;
2173 size_t descIndex = 0;
2174 foreach_pldm_downstream_device(devs, dev, rc)
2175 {
2176 struct pldm_descriptor desc;
2177
2178 ASSERT_LT(devIndex, expected_devices.size());
2179
2180 const struct pldm_downstream_device* expectedDev =
2181 &expected_devices[devIndex];
2182
2183 EXPECT_EQ(dev.downstream_device_index,
2184 expectedDev->downstream_device_index);
2185 EXPECT_EQ(dev.downstream_descriptor_count,
2186 expectedDev->downstream_descriptor_count);
2187
2188 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2189 {
2190 ASSERT_LT(descIndex, expected_descriptors.size());
2191
2192 const struct pldm_descriptor* expectedDesc =
2193 &expected_descriptors[descIndex];
2194
2195 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2196 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2197 EXPECT_EQ(memcmp(desc.descriptor_data,
2198 expectedDesc->descriptor_data,
2199 expectedDesc->descriptor_length),
2200 0);
2201
2202 descIndex++;
2203 }
2204 ASSERT_EQ(rc, 0);
2205
2206 devIndex++;
2207 }
2208 ASSERT_EQ(rc, 0);
2209 EXPECT_EQ(devIndex, 2);
2210 EXPECT_EQ(descIndex, 3);
2211}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302212
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302213TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2214{
2215 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2216 {0, 1},
2217 {1, 2},
2218 }};
2219
2220 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2221 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2222 &iana_pen_dmtf},
2223 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2224 &iana_pen_openbmc},
2225 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2226 &iana_pen_dmtf},
2227 }};
2228
2229 constexpr uint32_t downstream_devices_len = 30;
2230 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2231 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2232 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2233 const uint32_t downstream_devices_length_resp =
2234 htole32(downstream_devices_len);
2235 constexpr uint16_t number_of_downstream_devices_resp = 2;
2236 constexpr size_t payloadLen =
2237 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2238
Patrick Williamsf37edd72024-12-18 11:22:58 -05002239 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302240 PLDM_MSG_DEFINE_P(response, payloadLen);
2241 struct pldm_downstream_device_iter devs;
2242 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302243 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302244 int rc = 0;
2245
2246 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2247 ASSERT_EQ(rc, 0);
2248
2249 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2250 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2251 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2252 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2253 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2254
2255 /* Downstream device */
2256 pldm_msgbuf_insert_uint16(buf, 0);
2257 pldm_msgbuf_insert_uint8(buf, 1);
2258
2259 /* Device descriptor */
2260 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2261 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2262 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2263
2264 /* Downstream device */
2265 pldm_msgbuf_insert_uint16(buf, 1);
2266 pldm_msgbuf_insert_uint8(buf, 2);
2267
2268 /* Device descriptor */
2269 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2270 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2271 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2272
2273 /* Device descriptor */
2274 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2275 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2276 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2277
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302278 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302279
2280 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2281 &resp_data, &devs);
2282
Unive Tien71e935c2024-11-25 17:21:43 +08002283 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302284 EXPECT_EQ(resp_data.number_of_downstream_devices,
2285 number_of_downstream_devices_resp);
2286
2287 size_t devIndex = 0;
2288 size_t descIndex = 0;
2289 foreach_pldm_downstream_device(devs, dev, rc)
2290 {
2291 struct pldm_descriptor desc;
2292
2293 ASSERT_LT(devIndex, expected_devices.size());
2294
2295 const struct pldm_downstream_device* expectedDev =
2296 &expected_devices[devIndex];
2297
2298 EXPECT_EQ(dev.downstream_device_index,
2299 expectedDev->downstream_device_index);
2300 EXPECT_EQ(dev.downstream_descriptor_count,
2301 expectedDev->downstream_descriptor_count);
2302
2303 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2304 {
2305 ASSERT_LT(descIndex, expected_descriptors.size());
2306
2307 const struct pldm_descriptor* expectedDesc =
2308 &expected_descriptors[descIndex];
2309
2310 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2311 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2312 EXPECT_EQ(memcmp(desc.descriptor_data,
2313 expectedDesc->descriptor_data,
2314 expectedDesc->descriptor_length),
2315 0);
2316
2317 descIndex++;
2318 }
2319 ASSERT_EQ(rc, 0);
2320
2321 devIndex++;
2322 }
2323 ASSERT_EQ(rc, 0);
2324 EXPECT_EQ(devIndex, 2);
2325 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002326}
2327
2328TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2329{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302330 constexpr size_t payloadLen = sizeof(uint8_t);
2331
Chris Wang458475a2024-03-26 17:59:19 +08002332 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302333 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302334 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002335
2336 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302337 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2338 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002339 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002340
2341 // Test not PLDM_SUCCESS completion code
2342 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302343 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2344 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002345 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002346 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2347
2348 // Test payload length less than minimum length
2349 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302350 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2351 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002352
Unive Tien71e935c2024-11-25 17:21:43 +08002353 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002354}
2355
2356TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2357{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302358 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002359 // 1 descriptor
2360 constexpr uint32_t actualDownstreamDevicesLen = 9;
2361 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2362 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2363 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302364 constexpr uint16_t number_of_downstream_devices_resp = 1;
2365 constexpr size_t payloadLen =
2366 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2367 actualDownstreamDevicesLen;
2368
Chris Wang458475a2024-03-26 17:59:19 +08002369 const uint32_t downstream_devices_length_resp =
2370 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002371
Andrew Jefferydec237b2024-11-08 14:33:45 +10302372 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302373 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302374 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302375 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302376 void* devicesStart = NULL;
2377 size_t devicesLen;
2378 int rc = 0;
2379
2380 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302381 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002382
2383 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2384 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2385 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2386 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2387 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302388 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002389
Andrew Jefferya1896962025-03-03 21:41:25 +10302390 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2391
Chris Wang458475a2024-03-26 17:59:19 +08002392 /** Filling descriptor data, the correctness of the downstream devices data
2393 * is not checked in this test case so filling with 0xff
2394 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302395 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2396 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002397
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302398 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2399 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002400 0);
Chris Wang458475a2024-03-26 17:59:19 +08002401}
2402
2403TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2404{
2405 constexpr uint32_t actualDownstreamDevicesLen = 0;
2406 constexpr uint16_t number_of_downstream_devices_resp = 1;
2407 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2408 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2409 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302410 constexpr size_t payloadLen =
2411 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2412
Chris Wang458475a2024-03-26 17:59:19 +08002413 const uint32_t downstream_devices_length_resp =
2414 htole32(actualDownstreamDevicesLen);
2415
Andrew Jefferydec237b2024-11-08 14:33:45 +10302416 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302417 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302418 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302419 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302420 int rc = 0;
2421
2422 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2423 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002424
2425 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2426 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2427 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2428 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2429 // Inject error buffer size
2430 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
Andrew Jefferya1896962025-03-03 21:41:25 +10302431 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang458475a2024-03-26 17:59:19 +08002432
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302433 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2434 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002435
Unive Tien71e935c2024-11-25 17:21:43 +08002436 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002437}
2438
Chris Wangb6ef35b2024-07-03 09:35:42 +08002439TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2440{
2441 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302442 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002443 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002444 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302445 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002446 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302447 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002448 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2449
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302450 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002451 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002452 EXPECT_EQ(rc, 0);
2453
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302454 std::array<uint8_t,
2455 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002456 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2457 EXPECT_EQ(requestMsg, expectedReq);
2458}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002459
Chris Wangb6ef35b2024-07-03 09:35:42 +08002460TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2461{
2462 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002463 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302464 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002465 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002466 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302467 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002468 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302469 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002470 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2471
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302472 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002473 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002474 EXPECT_EQ(rc, -EBADMSG);
2475}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002476
Chris Wangb6ef35b2024-07-03 09:35:42 +08002477TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2478{
2479 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002480 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302481 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Andrew Jeffery53b08672025-03-04 12:26:18 +10302482 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002483 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302484 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
Chris Wangb6ef35b2024-07-03 09:35:42 +08002485 1 /* inject erro length*/;
2486
2487 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302488 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002489 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2490
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302491 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002492 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002493 EXPECT_EQ(rc, -EOVERFLOW);
2494}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002495
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302496TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002497{
Chris Wangb6ef35b2024-07-03 09:35:42 +08002498 constexpr uint16_t downstreamDeviceCount = 1;
2499 constexpr uint8_t activeComponentVersionStringLength = 8;
2500 constexpr uint8_t pendingComponentVersionStringLength = 8;
2501 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302502 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002503 activeComponentVersionStringLength +
2504 pendingComponentVersionStringLength;
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302505 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002506 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2507 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2508 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302509 constexpr size_t payload_len =
2510 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2511 downstreamDeviceParamTableLen;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002512
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302513 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302514 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302515 int rc = 0;
2516
2517 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302518 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002519
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302520 // Table 24
2521 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002522 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2523 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302524
2525 // Table 25
Chris Wangb6ef35b2024-07-03 09:35:42 +08002526 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2527 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2528
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302529 // Table 26
2530 pldm_msgbuf_insert_uint16(buf, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002531
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302532 // - Active metadata
2533 pldm_msgbuf_insert_uint32(buf, 0);
2534 pldm_msgbuf_insert_uint8(buf, 1);
2535 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2536 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2537 ASSERT_EQ(rc, 0);
2538
2539 // - Pending metadata
2540 pldm_msgbuf_insert_uint32(buf, 0);
2541 pldm_msgbuf_insert_uint8(buf, 1);
2542 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2543 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2544 ASSERT_EQ(rc, 0);
2545
2546 // - Methods and capabilities
2547 pldm_msgbuf_insert_uint16(buf, 1);
2548 pldm_msgbuf_insert_uint32(buf, 0);
2549
2550 // - Version strings
2551 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2552 "abcdefgh", 8);
2553 ASSERT_EQ(rc, 0);
2554 rc = pldm__msgbuf_insert_array_void(
2555 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2556 ASSERT_EQ(rc, 0);
2557
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302558 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302559 ASSERT_EQ(rc, 0);
2560
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302561 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302562 struct pldm_downstream_device_parameters_iter iter = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002563
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302564 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2565 &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002566
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302567 ASSERT_EQ(rc, 0);
2568 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002569 EXPECT_EQ(resp_data.next_data_transfer_handle,
2570 next_data_transfer_handle_resp);
2571 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2572 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302573
2574 struct pldm_downstream_device_parameters_entry entry;
2575 size_t entries = 0;
2576 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2577 {
2578 EXPECT_EQ(entry.downstream_device_index, 0);
2579 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2580 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2581 EXPECT_EQ(entry.active_comp_ver_str_len,
2582 activeComponentVersionStringLength);
2583 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2584 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2585 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2586 EXPECT_EQ(entry.pending_comp_ver_str_len,
2587 pendingComponentVersionStringLength);
2588 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2589 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2590 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2591 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2592 entry.active_comp_ver_str_len));
2593 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2594 entry.pending_comp_ver_str_len));
2595 entries++;
2596 }
2597 EXPECT_EQ(rc, 0);
2598 EXPECT_EQ(entries, 1);
2599}
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302600
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302601TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2602{
2603 /** Count is not fixed here taking it as 1, and the downstream device's
2604 * version strings length are set to 8
2605 */
2606 constexpr uint16_t downstreamDeviceCount = 2;
2607 constexpr uint8_t activeComponentVersionStringLength = 8;
2608 constexpr uint8_t pendingComponentVersionStringLength = 9;
2609 constexpr size_t downstreamDeviceParamTableLen =
2610 static_cast<size_t>(downstreamDeviceCount *
2611 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2612 activeComponentVersionStringLength +
2613 pendingComponentVersionStringLength));
2614 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2615 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2616 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2617 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2618 constexpr size_t payload_len =
2619 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2620 downstreamDeviceParamTableLen;
2621
2622 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302623 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302624 int rc = 0;
2625
2626 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302627 ASSERT_EQ(rc, 0);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302628
2629 // Table 24
2630 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2631 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2632 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2633
2634 // Table 25
2635 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2636 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2637
2638 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2639 table = {{{
2640 0,
2641 0,
2642 1,
2643 8,
2644 "20241206",
2645 0,
2646 1,
2647 9,
2648 "20241209",
2649 {1},
2650 {0},
2651 "active_0",
2652 "pending_0",
2653 },
2654 {
2655 1,
2656 0,
2657 1,
2658 8,
2659 "20241209",
2660 0,
2661 1,
2662 9,
2663 "20241206",
2664 {1},
2665 {0},
2666 "active_1",
2667 "pending_1",
2668 }}};
2669 for (const auto& e : table)
2670 {
2671 // Table 26
2672 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2673
2674 // - Active metadata
2675 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2676 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2677 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2678 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2679 sizeof(e.active_comp_release_date));
2680 ASSERT_EQ(rc, 0);
2681
2682 // - Pending metadata
2683 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2684 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2685 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2686 rc =
2687 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2688 sizeof(e.pending_comp_release_date));
2689 ASSERT_EQ(rc, 0);
2690
2691 // - Methods and capabilities
2692 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2693 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2694
2695 // - Version strings
2696 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2697 e.active_comp_ver_str,
2698 e.active_comp_ver_str_len);
2699 ASSERT_EQ(rc, 0);
2700 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2701 e.pending_comp_ver_str,
2702 e.pending_comp_ver_str_len);
2703 ASSERT_EQ(rc, 0);
2704 }
2705
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302706 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302707 ASSERT_EQ(rc, 0);
2708
2709 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2710 struct pldm_downstream_device_parameters_iter iter = {};
2711
2712 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2713 &resp_data, &iter);
2714
2715 ASSERT_EQ(rc, 0);
2716 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2717 EXPECT_EQ(resp_data.next_data_transfer_handle,
2718 next_data_transfer_handle_resp);
2719 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2720 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2721
2722 struct pldm_downstream_device_parameters_entry entry;
2723 size_t entryIndex = 0;
2724 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2725 {
2726 ASSERT_LE(entryIndex, table.size());
2727
2728 EXPECT_EQ(table[entryIndex].downstream_device_index,
2729 entry.downstream_device_index);
2730 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2731 entry.active_comp_comparison_stamp);
2732 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2733 entry.active_comp_ver_str_type);
2734 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2735 entry.active_comp_ver_str_len);
2736 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2737 &entry.active_comp_release_date[0]);
2738 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2739 entry.pending_comp_comparison_stamp);
2740 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2741 entry.pending_comp_ver_str_type);
2742 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2743 entry.pending_comp_ver_str_len);
2744 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2745 &entry.pending_comp_release_date[0]);
2746 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2747 entry.comp_activation_methods.value);
2748 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2749 entry.capabilities_during_update.value);
2750 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2751 entry.active_comp_ver_str,
2752 table[entryIndex].active_comp_ver_str_len));
2753 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2754 entry.pending_comp_ver_str,
2755 table[entryIndex].pending_comp_ver_str_len));
2756 entryIndex++;
2757 }
2758 EXPECT_EQ(rc, 0);
2759 EXPECT_EQ(entryIndex, table.size());
Chris Wangb6ef35b2024-07-03 09:35:42 +08002760}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002761
Chris Wangb6ef35b2024-07-03 09:35:42 +08002762TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2763{
2764 /** Count is not fixed here taking it as 1, and the downstream device's
2765 * version strings length are set to 8
2766 */
2767 constexpr uint16_t downstreamDeviceCount = 1;
2768 constexpr uint8_t activeComponentVersionStringLength = 8;
2769 constexpr uint8_t pendingComponentVersionStringLength = 8;
2770 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302771 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002772 activeComponentVersionStringLength +
2773 pendingComponentVersionStringLength;
2774 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2775 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2776 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2777 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2778
2779 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302780 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002781 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2782 responseMsg{};
2783
2784 int rc = 0;
2785
Andrew Jefferya1896962025-03-03 21:41:25 +10302786 PLDM_MSGBUF_DEFINE_P(buf);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002787 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2788 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10302789 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002790
2791 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2792 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2793 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2794 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2795 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
Andrew Jefferya1896962025-03-03 21:41:25 +10302796 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002797
2798 /** Filling paramter table, the correctness of the downstream devices data
2799 * is not checked in this test case so filling with 0xff
2800 */
2801 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302802 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002803 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2804 0xff);
2805
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302806 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002807 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302808 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302809 struct pldm_downstream_device_parameters_iter iter;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002810
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302811 rc = decode_get_downstream_firmware_parameters_resp(
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302812 response, responseMsg.size() - hdrSize, &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002813 EXPECT_EQ(rc, 0);
2814
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302815 struct pldm_downstream_device_parameters_entry entry;
2816 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2817 {
2818 FAIL();
2819 }
2820 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002821}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002822
Andrew Jeffery9c766792022-08-10 23:12:49 +09302823TEST(RequestUpdate, goodPathEncodeRequest)
2824{
2825 constexpr uint8_t instanceId = 1;
2826 constexpr uint32_t maxTransferSize = 512;
2827 constexpr uint16_t numOfComp = 3;
2828 constexpr uint8_t maxOutstandingTransferReq = 2;
2829 constexpr uint16_t pkgDataLen = 0x1234;
2830 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2831 constexpr uint8_t compImgSetVerStrLen =
2832 static_cast<uint8_t>(compImgSetVerStr.size());
2833 variable_field compImgSetVerStrInfo{};
2834 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302835 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302836 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2837 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2838
2839 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2840 compImgSetVerStrLen>
2841 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302842 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302843 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2844
2845 auto rc = encode_request_update_req(
2846 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2847 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2848 &compImgSetVerStrInfo, requestMsg,
2849 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2850 EXPECT_EQ(rc, PLDM_SUCCESS);
2851
2852 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2853 compImgSetVerStrLen>
2854 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2855 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2856 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2857 EXPECT_EQ(request, outRequest);
2858}
2859
2860TEST(RequestUpdate, errorPathEncodeRequest)
2861{
2862 constexpr uint8_t instanceId = 1;
2863 uint32_t maxTransferSize = 512;
2864 constexpr uint16_t numOfComp = 3;
2865 uint8_t maxOutstandingTransferReq = 2;
2866 constexpr uint16_t pkgDataLen = 0x1234;
2867 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2868 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2869 variable_field compImgSetVerStrInfo{};
2870 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302871 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302872 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2873 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2874
2875 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2876 compImgSetVerStr.size()>
2877 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302878 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302879 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2880
2881 auto rc = encode_request_update_req(
2882 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2883 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2884 requestMsg,
2885 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2886 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2887
2888 compImgSetVerStrInfo.ptr = nullptr;
2889 rc = encode_request_update_req(
2890 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2891 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2892 &compImgSetVerStrInfo, requestMsg,
2893 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2894 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2895 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302896 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302897 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2898
2899 rc = encode_request_update_req(
2900 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2901 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2902 &compImgSetVerStrInfo, nullptr,
2903 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2904 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2905
2906 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2907 maxOutstandingTransferReq, pkgDataLen,
2908 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2909 &compImgSetVerStrInfo, requestMsg, 0);
2910 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2911
2912 compImgSetVerStrLen = 0;
2913 rc = encode_request_update_req(
2914 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2915 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2916 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2917 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2918 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2919
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002920 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302921 rc = encode_request_update_req(
2922 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2923 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2924 &compImgSetVerStrInfo, nullptr,
2925 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2926 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2927 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2928
2929 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2930 rc = encode_request_update_req(
2931 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2932 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2933 &compImgSetVerStrInfo, nullptr,
2934 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2935 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2936 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2937
Andrew Jefferya1cd72b2025-05-09 12:26:06 +09302938 maxOutstandingTransferReq = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302939 rc = encode_request_update_req(
2940 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2941 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2942 &compImgSetVerStrInfo, nullptr,
2943 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2944 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2945 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2946
2947 rc = encode_request_update_req(
2948 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2949 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2950 &compImgSetVerStrInfo, nullptr,
2951 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2952 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2953}
2954
2955TEST(RequestUpdate, goodPathDecodeResponse)
2956{
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002957 /* Test a success completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302958 constexpr uint16_t fdMetaDataLen = 1024;
2959 constexpr uint8_t fdWillSendPkgData = 1;
2960 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2961 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2962
2963 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302964 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302965 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2966 uint8_t outCompletionCode = 0;
2967 uint16_t outFdMetaDataLen = 0;
2968 uint8_t outFdWillSendPkgData = 0;
2969
2970 auto rc = decode_request_update_resp(
2971 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2972 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2973 EXPECT_EQ(rc, PLDM_SUCCESS);
2974 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2975 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2976 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2977
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002978#ifdef LIBPLDM_API_TESTING
2979 /* Check the success roundtrip matches */
2980 PLDM_MSG_DEFINE_P(enc, 1000);
2981 size_t enc_payload_len = 1000;
2982 const struct pldm_request_update_resp resp_data = {
2983 .completion_code = PLDM_SUCCESS,
2984 .fd_meta_data_len = outFdMetaDataLen,
2985 .fd_will_send_pkg_data = outFdWillSendPkgData,
2986 };
2987 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2988 &enc_payload_len);
2989 EXPECT_EQ(rc, PLDM_SUCCESS);
2990 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2991 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2992 requestUpdateResponse1.end(), enc_buf + hdrSize));
2993 check_response(enc, PLDM_REQUEST_UPDATE);
2994#endif
2995
2996 /* Test a failure completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302997 outCompletionCode = 0;
2998 outFdMetaDataLen = 0;
2999 outFdWillSendPkgData = 0;
3000
3001 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
3002 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3003 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303004 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303005 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
3006 rc = decode_request_update_resp(
3007 responseMsg2, requestUpdateResponse2.size() - hdrSize,
3008 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
3009 EXPECT_EQ(rc, PLDM_SUCCESS);
3010 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3011}
3012
3013TEST(RequestUpdate, errorPathDecodeResponse)
3014{
3015 constexpr std::array<uint8_t,
3016 hdrSize + sizeof(pldm_request_update_resp) - 1>
3017 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
3018
3019 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303020 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303021 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
3022 uint8_t outCompletionCode = 0;
3023 uint16_t outFdMetaDataLen = 0;
3024 uint8_t outFdWillSendPkgData = 0;
3025
3026 auto rc = decode_request_update_resp(
3027 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3028 &outFdMetaDataLen, &outFdWillSendPkgData);
3029 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3030
3031 rc = decode_request_update_resp(
3032 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
3033 &outFdMetaDataLen, &outFdWillSendPkgData);
3034 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3035
3036 rc = decode_request_update_resp(
3037 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3038 nullptr, &outFdWillSendPkgData);
3039 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3040
3041 rc = decode_request_update_resp(
3042 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3043 &outFdMetaDataLen, nullptr);
3044 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3045
3046 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
3047 &outFdMetaDataLen, &outFdWillSendPkgData);
3048 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3049
3050 rc = decode_request_update_resp(
3051 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3052 &outFdMetaDataLen, &outFdWillSendPkgData);
3053 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3054}
3055
Sora Su06eadd02025-05-27 11:28:51 +08003056#ifdef LIBPLDM_API_TESTING
3057TEST(RequestDownstreamDeviceUpdate, goodPathEncodeRequest)
3058{
3059 constexpr uint8_t instanceId = 1;
3060
3061 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3062 request{};
3063
3064 auto requestMsg = new (request.data()) pldm_msg;
3065
3066 constexpr struct pldm_request_downstream_device_update_req req_data = {
3067 .maximum_downstream_device_transfer_size = 512,
3068 .maximum_outstanding_transfer_requests = 2,
3069 .downstream_device_package_data_length = 0x1234,
3070 };
3071 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3072
3073 auto rc = encode_request_downstream_device_update_req(
3074 instanceId, &req_data, requestMsg, &enc_payload_len);
3075
3076 EXPECT_EQ(rc, 0);
3077
3078 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3079 outRequest{0x81, 0x05, 0x20, 0x00, 0x02, 0x00, 0x00, 0x02, 0x34, 0x12};
3080 EXPECT_EQ(request, outRequest);
3081}
3082#endif // LIBPLDM_API_TESTING
3083
3084#ifdef LIBPLDM_API_TESTING
3085TEST(RequestDownstreamDeviceUpdate, errorPathEncodeRequest)
3086{
3087 constexpr uint8_t instanceId = 1;
3088 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3089
3090 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3091 request{};
3092
3093 struct pldm_request_downstream_device_update_req req_data = {
3094 .maximum_downstream_device_transfer_size = 512,
3095 .maximum_outstanding_transfer_requests = 2,
3096 .downstream_device_package_data_length = 0x1234,
3097 };
3098
3099 auto requestMsg = new (request.data()) pldm_msg;
3100
3101 auto rc = encode_request_downstream_device_update_req(
3102 instanceId, nullptr, requestMsg, &enc_payload_len);
3103 EXPECT_EQ(rc, -EINVAL);
3104 rc = encode_request_downstream_device_update_req(
3105 instanceId, &req_data, requestMsg, &enc_payload_len);
3106 EXPECT_EQ(rc, 0);
3107
3108 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3109 nullptr, &enc_payload_len);
3110 EXPECT_EQ(rc, -EINVAL);
3111 rc = encode_request_downstream_device_update_req(
3112 instanceId, &req_data, requestMsg, &enc_payload_len);
3113 EXPECT_EQ(rc, 0);
3114
3115 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3116 requestMsg, nullptr);
3117 EXPECT_EQ(rc, -EINVAL);
3118 rc = encode_request_downstream_device_update_req(
3119 instanceId, &req_data, requestMsg, &enc_payload_len);
3120 EXPECT_EQ(rc, 0);
3121
3122 enc_payload_len =
3123 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES) - 1;
3124 rc = encode_request_downstream_device_update_req(
3125 instanceId, &req_data, requestMsg, &enc_payload_len);
3126 EXPECT_EQ(rc, -EOVERFLOW);
3127 enc_payload_len =
3128 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES);
3129 rc = encode_request_downstream_device_update_req(
3130 instanceId, &req_data, requestMsg, &enc_payload_len);
3131 EXPECT_EQ(rc, 0);
3132
3133 req_data.maximum_downstream_device_transfer_size = 31;
3134 rc = encode_request_downstream_device_update_req(
3135 instanceId, &req_data, requestMsg, &enc_payload_len);
3136 EXPECT_EQ(rc, -EINVAL);
3137 req_data.maximum_downstream_device_transfer_size =
3138 PLDM_FWUP_BASELINE_TRANSFER_SIZE;
3139
3140 req_data.maximum_outstanding_transfer_requests = 0;
3141 rc = encode_request_downstream_device_update_req(
3142 instanceId, &req_data, requestMsg, &enc_payload_len);
3143 EXPECT_EQ(rc, -EINVAL);
3144 req_data.maximum_outstanding_transfer_requests = 2;
3145 rc = encode_request_downstream_device_update_req(
3146 instanceId, &req_data, requestMsg, &enc_payload_len);
3147 EXPECT_EQ(rc, 0);
3148}
3149#endif // LIBPLDM_API_TESTING
3150
3151#ifdef LIBPLDM_API_TESTING
3152TEST(RequestDownstreamDeviceUpdate, goodPathDecodeResponse)
3153{
3154 /* Test a success completion code */
3155 constexpr uint16_t ddMetaDataLen = 1024;
3156 constexpr uint8_t ddWillSendPkgData = 1;
3157 constexpr uint16_t getPkgDataMaxTransferSize = 512;
3158 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3159 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00,
3160 0x04, 0x01, 0x00, 0x02};
3161
3162 auto responseMsg1 = new (requestUpdateResponse1.data()) pldm_msg;
3163
3164 struct pldm_request_downstream_device_update_resp resp_data1 = {
3165 .completion_code = 0,
3166 .downstream_device_meta_data_length = 0,
3167 .downstream_device_will_send_get_package_data = 0,
3168 .get_package_data_maximum_transfer_size = 0};
3169
3170 auto rc = decode_request_downstream_device_update_resp(
3171 responseMsg1, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3172 &resp_data1);
3173 EXPECT_EQ(rc, 0);
3174 EXPECT_EQ(resp_data1.completion_code, PLDM_SUCCESS);
3175 EXPECT_EQ(resp_data1.downstream_device_meta_data_length, ddMetaDataLen);
3176 EXPECT_EQ(resp_data1.downstream_device_will_send_get_package_data,
3177 ddWillSendPkgData);
3178 EXPECT_EQ(resp_data1.get_package_data_maximum_transfer_size,
3179 getPkgDataMaxTransferSize);
3180
3181 /* Test a failure completion code */
3182 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3183 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3184
3185 auto responseMsg2 = new (requestUpdateResponse2.data()) pldm_msg;
3186
3187 struct pldm_request_downstream_device_update_resp resp_data2 = {
3188 .completion_code = 0,
3189 .downstream_device_meta_data_length = 0,
3190 .downstream_device_will_send_get_package_data = 0,
3191 .get_package_data_maximum_transfer_size = 0};
3192
3193 rc = decode_request_downstream_device_update_resp(
3194 responseMsg2, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3195 &resp_data2);
3196 EXPECT_EQ(rc, 0);
3197 EXPECT_EQ(resp_data2.completion_code, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3198}
3199#endif // LIBPLDM_API_TESTING
3200
3201#ifdef LIBPLDM_API_TESTING
3202TEST(RequestDownstreamDeviceUpdate, errorPathDecodeResponse)
3203{
3204 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3205 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00,
3206 0x04, 0x01, 0x00, 0x02};
3207
3208 auto responseMsg = new (requestUpdateResponse.data()) pldm_msg;
3209
3210 struct pldm_request_downstream_device_update_resp resp_data = {
3211 .completion_code = 0,
3212 .downstream_device_meta_data_length = 0,
3213 .downstream_device_will_send_get_package_data = 0,
3214 .get_package_data_maximum_transfer_size = 0};
3215
3216 auto rc = decode_request_downstream_device_update_resp(
3217 nullptr, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, &resp_data);
3218 EXPECT_EQ(rc, -EINVAL);
3219
3220 rc = decode_request_downstream_device_update_resp(
3221 responseMsg, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, nullptr);
3222 EXPECT_EQ(rc, -EINVAL);
3223
3224 rc = decode_request_downstream_device_update_resp(responseMsg, 0,
3225 &resp_data);
3226 EXPECT_EQ(rc, -EOVERFLOW);
3227}
3228#endif // LIBPLDM_API_TESTING
3229
Andrew Jeffery9c766792022-08-10 23:12:49 +09303230TEST(PassComponentTable, goodPathEncodeRequest)
3231{
3232 constexpr uint8_t instanceId = 1;
3233 constexpr uint16_t compIdentifier = 400;
3234 constexpr uint8_t compClassificationIndex = 40;
3235 constexpr uint32_t compComparisonStamp = 0x12345678;
3236 constexpr std::string_view compVerStr = "0penBmcv1.1";
3237 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3238 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303239 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303240 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3241 compVerStrInfo.length = compVerStrLen;
3242
3243 std::array<uint8_t,
3244 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3245 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303246 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303247 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3248
3249 auto rc = encode_pass_component_table_req(
3250 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3251 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3252 compVerStrLen, &compVerStrInfo, requestMsg,
3253 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3254 EXPECT_EQ(rc, PLDM_SUCCESS);
3255
3256 std::array<uint8_t,
3257 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003258 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
3259 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
3260 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303261 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003262
3263#ifdef LIBPLDM_API_TESTING
3264 /* Check the roundtrip */
3265 struct pldm_pass_component_table_req_full req;
3266 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3267 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3268 rc =
3269 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
3270 ASSERT_EQ(rc, 0);
3271
3272 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
3273 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3274 EXPECT_EQ(req.comp_identifier, compIdentifier);
3275 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3276 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3277 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3278 EXPECT_EQ(req.version.str_len, compVerStrLen);
3279 EXPECT_TRUE(std::equal(req.version.str_data,
3280 req.version.str_data + req.version.str_len,
3281 compVerStr.data()));
3282#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303283}
3284
3285TEST(PassComponentTable, errorPathEncodeRequest)
3286{
3287 constexpr uint8_t instanceId = 1;
3288 constexpr uint16_t compIdentifier = 400;
3289 constexpr uint8_t compClassificationIndex = 40;
3290 constexpr uint32_t compComparisonStamp = 0x12345678;
3291 constexpr std::string_view compVerStr = "0penBmcv1.1";
3292 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3293 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303294 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303295 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3296 compVerStrInfo.length = compVerStrLen;
3297
3298 std::array<uint8_t,
3299 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3300 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303301 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303302 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3303
3304 auto rc = encode_pass_component_table_req(
3305 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3306 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3307 compVerStrLen, nullptr, requestMsg,
3308 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3309 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3310
3311 compVerStrInfo.ptr = nullptr;
3312 rc = encode_pass_component_table_req(
3313 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3314 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3315 compVerStrLen, &compVerStrInfo, requestMsg,
3316 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3317 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303318 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303319 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3320
3321 rc = encode_pass_component_table_req(
3322 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3323 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3324 compVerStrLen, &compVerStrInfo, nullptr,
3325 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3326 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3327
3328 rc = encode_pass_component_table_req(
3329 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3330 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3331 compVerStrLen, &compVerStrInfo, requestMsg,
3332 sizeof(pldm_pass_component_table_req));
3333 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3334
3335 rc = encode_pass_component_table_req(
3336 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3337 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3338 &compVerStrInfo, requestMsg,
3339 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3340 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3341
3342 rc = encode_pass_component_table_req(
3343 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3344 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3345 compVerStrLen - 1, &compVerStrInfo, requestMsg,
3346 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3347 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3348
3349 rc = encode_pass_component_table_req(
3350 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3351 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3352 compVerStrLen, &compVerStrInfo, requestMsg,
3353 sizeof(pldm_pass_component_table_req) + compVerStrLen);
Manojkiran Eda3643e742025-05-19 12:03:54 +05303354 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG);
Andrew Jeffery9c766792022-08-10 23:12:49 +09303355
3356 rc = encode_pass_component_table_req(
3357 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3358 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3359 compVerStrLen, &compVerStrInfo, requestMsg,
3360 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3361 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3362}
3363
3364TEST(PassComponentTable, goodPathDecodeResponse)
3365{
3366 constexpr std::array<uint8_t,
3367 hdrSize + sizeof(pldm_pass_component_table_resp)>
3368 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3369 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303370 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303371 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3372
3373 uint8_t completionCode = 0;
3374 uint8_t compResp = 0;
3375 uint8_t compRespCode = 0;
3376
3377 auto rc = decode_pass_component_table_resp(
3378 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3379 &compResp, &compRespCode);
3380
3381 EXPECT_EQ(rc, PLDM_SUCCESS);
3382 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3383 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3384 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3385
3386 constexpr std::array<uint8_t,
3387 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003388 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303389 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303390 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303391 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3392 rc = decode_pass_component_table_resp(
3393 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3394 &compResp, &compRespCode);
3395
3396 EXPECT_EQ(rc, PLDM_SUCCESS);
3397 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3398 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3399 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3400
3401 constexpr std::array<uint8_t,
3402 hdrSize + sizeof(pldm_pass_component_table_resp)>
3403 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3404 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303405 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303406 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3407
3408 rc = decode_pass_component_table_resp(
3409 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3410 &compResp, &compRespCode);
3411
3412 EXPECT_EQ(rc, PLDM_SUCCESS);
3413 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3414}
3415
3416TEST(PassComponentTable, errorPathDecodeResponse)
3417{
3418 constexpr std::array<uint8_t,
3419 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3420 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3421 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303422 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303423 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3424
3425 uint8_t completionCode = 0;
3426 uint8_t compResp = 0;
3427 uint8_t compRespCode = 0;
3428
3429 auto rc = decode_pass_component_table_resp(
3430 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3431 &compResp, &compRespCode);
3432 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3433
3434 rc = decode_pass_component_table_resp(
3435 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3436 &compResp, &compRespCode);
3437 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3438
3439 rc = decode_pass_component_table_resp(
3440 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3441 &completionCode, nullptr, &compRespCode);
3442 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3443
3444 rc = decode_pass_component_table_resp(
3445 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3446 &completionCode, &compResp, nullptr);
3447 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3448
3449 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3450 &compResp, &compRespCode);
3451 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3452
3453 rc = decode_pass_component_table_resp(
3454 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3455 &completionCode, &compResp, &compRespCode);
3456 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3457
3458 constexpr std::array<uint8_t,
3459 hdrSize + sizeof(pldm_pass_component_table_resp)>
3460 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3461 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303462 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303463 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3464 rc = decode_pass_component_table_resp(
3465 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3466 &compResp, &compRespCode);
3467 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3468
3469 constexpr std::array<uint8_t,
3470 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003471 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303472 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303473 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303474 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3475 rc = decode_pass_component_table_resp(
3476 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3477 &compResp, &compRespCode);
3478 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3479
3480 constexpr std::array<uint8_t,
3481 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003482 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303483 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303484 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303485 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3486 rc = decode_pass_component_table_resp(
3487 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3488 &compResp, &compRespCode);
3489 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3490}
3491
3492TEST(UpdateComponent, goodPathEncodeRequest)
3493{
3494 constexpr uint8_t instanceId = 2;
3495 constexpr uint16_t compIdentifier = 500;
3496 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003497 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303498 constexpr uint32_t compImageSize = 4096;
3499 constexpr bitfield32_t updateOptionFlags{1};
3500 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3501 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3502 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303503 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303504 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3505 compVerStrInfo.length = compVerStrLen;
3506
3507 std::array<uint8_t,
3508 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3509 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303510 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303511 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3512
3513 auto rc = encode_update_component_req(
3514 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3515 compComparisonStamp, compImageSize, updateOptionFlags,
3516 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3517 sizeof(pldm_update_component_req) + compVerStrLen);
3518 EXPECT_EQ(rc, PLDM_SUCCESS);
3519
3520 std::array<uint8_t,
3521 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003522 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3523 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3524 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3525 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303526 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003527
3528#ifdef LIBPLDM_API_TESTING
3529 /* Check the roundtrip */
3530 struct pldm_update_component_req_full req;
3531 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3532 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3533 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3534 ASSERT_EQ(rc, 0);
3535
3536 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3537 EXPECT_EQ(req.comp_identifier, compIdentifier);
3538 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3539 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3540 EXPECT_EQ(req.comp_image_size, compImageSize);
3541 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3542 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3543 EXPECT_EQ(req.version.str_len, compVerStrLen);
3544 EXPECT_TRUE(std::equal(req.version.str_data,
3545 req.version.str_data + req.version.str_len,
3546 compVerStr.data()));
3547#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303548}
3549
3550TEST(UpdateComponent, errorPathEncodeRequest)
3551{
3552 constexpr uint8_t instanceId = 2;
3553 constexpr uint16_t compIdentifier = 500;
3554 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003555 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303556 constexpr uint32_t compImageSize = 4096;
3557 constexpr bitfield32_t updateOptionFlags{1};
3558 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3559 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3560 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303561 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303562 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3563 compVerStrInfo.length = compVerStrLen;
3564
3565 std::array<uint8_t,
3566 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3567 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303568 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303569 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3570
3571 auto rc = encode_update_component_req(
3572 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3573 compComparisonStamp, compImageSize, updateOptionFlags,
3574 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3575 sizeof(pldm_update_component_req) + compVerStrLen);
3576 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3577
3578 compVerStrInfo.ptr = nullptr;
3579 rc = encode_update_component_req(
3580 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3581 compComparisonStamp, compImageSize, updateOptionFlags,
3582 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3583 sizeof(pldm_update_component_req) + compVerStrLen);
3584 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303585 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303586 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3587
3588 rc = encode_update_component_req(
3589 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3590 compComparisonStamp, compImageSize, updateOptionFlags,
3591 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3592 sizeof(pldm_update_component_req) + compVerStrLen);
3593 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3594
3595 rc = encode_update_component_req(
3596 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3597 compComparisonStamp, compImageSize, updateOptionFlags,
3598 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3599 sizeof(pldm_update_component_req));
3600 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3601
3602 rc = encode_update_component_req(
3603 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3604 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3605 compVerStrLen, &compVerStrInfo, requestMsg,
3606 sizeof(pldm_update_component_req) + compVerStrLen);
3607 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3608
3609 rc = encode_update_component_req(
3610 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3611 compComparisonStamp, compImageSize, updateOptionFlags,
3612 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3613 sizeof(pldm_update_component_req) + compVerStrLen);
3614 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3615
3616 rc = encode_update_component_req(
3617 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3618 compComparisonStamp, compImageSize, updateOptionFlags,
3619 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3620 sizeof(pldm_update_component_req) + compVerStrLen);
3621 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3622
3623 rc = encode_update_component_req(
3624 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3625 compComparisonStamp, compImageSize, updateOptionFlags,
3626 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3627 sizeof(pldm_update_component_req) + compVerStrLen);
3628 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3629}
3630
3631TEST(UpdateComponent, goodPathDecodeResponse)
3632{
3633 constexpr std::bitset<32> forceUpdateComp{1};
3634 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3635 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3636 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3637 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3638 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303639 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303640 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3641
3642 uint8_t completionCode = 0;
3643 uint8_t compCompatibilityResp = 0;
3644 uint8_t compCompatibilityRespCode = 0;
3645 bitfield32_t updateOptionFlagsEnabled{};
3646 uint16_t timeBeforeReqFWData = 0;
3647
3648 auto rc = decode_update_component_resp(
3649 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3650 &compCompatibilityResp, &compCompatibilityRespCode,
3651 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3652
3653 EXPECT_EQ(rc, PLDM_SUCCESS);
3654 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3655 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3656 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3657 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3658 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3659
3660 constexpr std::bitset<32> noFlags{};
3661 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3662 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3663 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3665 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303666 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303667 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3668 rc = decode_update_component_resp(
3669 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3670 &compCompatibilityResp, &compCompatibilityRespCode,
3671 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3672
3673 EXPECT_EQ(rc, PLDM_SUCCESS);
3674 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3675 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3676 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3677 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3678 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3679
3680 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3681 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3682 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303683 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303684 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3685
3686 rc = decode_update_component_resp(
3687 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3688 &compCompatibilityResp, &compCompatibilityRespCode,
3689 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3690
3691 EXPECT_EQ(rc, PLDM_SUCCESS);
3692 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3693}
3694
3695TEST(UpdateComponent, errorPathDecodeResponse)
3696{
3697 constexpr std::array<uint8_t,
3698 hdrSize + sizeof(pldm_update_component_resp) - 1>
3699 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3700 0x00, 0x00, 0x00, 0x00, 0x00};
3701 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303702 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303703 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3704
3705 uint8_t completionCode = 0;
3706 uint8_t compCompatibilityResp = 0;
3707 uint8_t compCompatibilityRespCode = 0;
3708 bitfield32_t updateOptionFlagsEnabled{};
3709 uint16_t timeBeforeReqFWData = 0;
3710
3711 auto rc = decode_update_component_resp(
3712 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3713 &compCompatibilityResp, &compCompatibilityRespCode,
3714 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3715 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3716
3717 rc = decode_update_component_resp(
3718 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3719 &compCompatibilityResp, &compCompatibilityRespCode,
3720 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3721 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3722
3723 rc = decode_update_component_resp(
3724 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3725 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3726 &timeBeforeReqFWData);
3727 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3728
3729 rc = decode_update_component_resp(
3730 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3731 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3732 &timeBeforeReqFWData);
3733 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3734
3735 rc = decode_update_component_resp(
3736 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3737 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3738 &timeBeforeReqFWData);
3739 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3740
3741 rc = decode_update_component_resp(
3742 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3743 &compCompatibilityResp, &compCompatibilityRespCode,
3744 &updateOptionFlagsEnabled, nullptr);
3745 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3746
3747 rc = decode_update_component_resp(
3748 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3749 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3750 &timeBeforeReqFWData);
3751 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3752
3753 rc = decode_update_component_resp(
3754 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3755 &compCompatibilityResp, &compCompatibilityRespCode,
3756 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3757 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3758
3759 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3760 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3761 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3762 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303763 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303764 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3765 rc = decode_update_component_resp(
3766 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3767 &compCompatibilityResp, &compCompatibilityRespCode,
3768 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3769 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3770
3771 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003772 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303773 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3774 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303775 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303776 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3777 rc = decode_update_component_resp(
3778 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3779 &compCompatibilityResp, &compCompatibilityRespCode,
3780 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3781 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3782
3783 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003784 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303785 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3786 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303787 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303788 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3789 rc = decode_update_component_resp(
3790 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3791 &compCompatibilityResp, &compCompatibilityRespCode,
3792 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3793 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3794}
3795
3796TEST(RequestFirmwareData, goodPathDecodeRequest)
3797{
3798 constexpr uint32_t offset = 300;
3799 constexpr uint32_t length = 255;
3800 constexpr std::array<uint8_t,
3801 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003802 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3803 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303804 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303805 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3806
3807 uint32_t outOffset = 0;
3808 uint32_t outLength = 0;
3809 auto rc = decode_request_firmware_data_req(
3810 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3811 &outLength);
3812
3813 EXPECT_EQ(rc, PLDM_SUCCESS);
3814 EXPECT_EQ(outOffset, offset);
3815 EXPECT_EQ(outLength, length);
3816}
3817
3818TEST(RequestFirmwareData, errorPathDecodeRequest)
3819{
3820 constexpr std::array<uint8_t,
3821 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003822 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3823 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303824 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303825 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3826
3827 uint32_t outOffset = 0;
3828 uint32_t outLength = 0;
3829 auto rc = decode_request_firmware_data_req(
3830 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3831 &outLength);
3832 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3833
3834 rc = decode_request_firmware_data_req(
3835 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3836 &outLength);
3837 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3838
3839 rc = decode_request_firmware_data_req(
3840 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3841 nullptr);
3842 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3843
3844 rc = decode_request_firmware_data_req(
3845 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3846 &outLength);
3847 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3848
3849 rc = decode_request_firmware_data_req(
3850 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3851 &outLength);
3852 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3853}
3854
3855TEST(RequestFirmwareData, goodPathEncodeResponse)
3856{
3857 constexpr uint8_t instanceId = 3;
3858 constexpr uint8_t completionCode = PLDM_SUCCESS;
3859 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3860 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3861 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003862 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3863 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3864 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3865 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303866 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3867 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3868 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003869 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3870 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3871 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3872 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303873 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303874 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3875 auto rc = encode_request_firmware_data_resp(
3876 instanceId, completionCode, responseMsg1,
3877 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3878 EXPECT_EQ(rc, PLDM_SUCCESS);
3879 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3880
3881 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3882 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3883 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3884 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303885 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303886 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3887 rc = encode_request_firmware_data_resp(
3888 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3889 sizeof(completionCode));
3890 EXPECT_EQ(rc, PLDM_SUCCESS);
3891 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3892}
3893
3894TEST(RequestFirmwareData, errorPathEncodeResponse)
3895{
3896 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303897 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303898 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3899 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3900 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3901
3902 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3903 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3904}
3905
3906TEST(TransferComplete, goodPathDecodeRequest)
3907{
3908 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3909 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3910 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3911 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303912 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303913 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3914 uint8_t outTransferResult = 0;
3915
3916 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3917 &outTransferResult);
3918 EXPECT_EQ(rc, PLDM_SUCCESS);
3919 EXPECT_EQ(outTransferResult, transferResult);
3920
3921 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3922 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3923 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303924 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303925 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3926 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3927 &outTransferResult);
3928 EXPECT_EQ(rc, PLDM_SUCCESS);
3929 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3930}
3931
3932TEST(TransferComplete, errorPathDecodeRequest)
3933{
3934 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3935 0x00};
3936 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303937 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303938 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3939 uint8_t outTransferResult = 0;
3940
3941 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3942 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3943
3944 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3945 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3946
3947 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3948 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3949}
3950
3951TEST(TransferComplete, goodPathEncodeResponse)
3952{
3953 constexpr uint8_t instanceId = 4;
3954 constexpr uint8_t completionCode = PLDM_SUCCESS;
3955 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3956 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3957 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3958 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3959 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303960 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303961 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3962 auto rc = encode_transfer_complete_resp(
3963 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3964 EXPECT_EQ(rc, PLDM_SUCCESS);
3965 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3966
3967 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3968 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3969 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3970 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3971 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303972 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303973 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3974 rc = encode_transfer_complete_resp(instanceId,
3975 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3976 responseMsg2, sizeof(completionCode));
3977 EXPECT_EQ(rc, PLDM_SUCCESS);
3978 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3979}
3980
3981TEST(TransferComplete, errorPathEncodeResponse)
3982{
3983 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3984 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303985 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303986 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3987 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3988 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3989
3990 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3991 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3992}
3993
3994TEST(VerifyComplete, goodPathDecodeRequest)
3995{
3996 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3997 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3998 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3999 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304000 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304001 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
4002 uint8_t outVerifyResult = 0;
4003
4004 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
4005 &outVerifyResult);
4006 EXPECT_EQ(rc, PLDM_SUCCESS);
4007 EXPECT_EQ(outVerifyResult, verifyResult);
4008
4009 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
4010 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
4011 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304012 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304013 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
4014 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
4015 &outVerifyResult);
4016 EXPECT_EQ(rc, PLDM_SUCCESS);
4017 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
4018}
4019
4020TEST(VerifyComplete, errorPathDecodeRequest)
4021{
4022 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
4023 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304024 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304025 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
4026 uint8_t outVerifyResult = 0;
4027
4028 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
4029 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4030
4031 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
4032 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4033
4034 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
4035 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4036}
4037
4038TEST(VerifyComplete, goodPathEncodeResponse)
4039{
4040 constexpr uint8_t instanceId = 5;
4041 constexpr uint8_t completionCode = PLDM_SUCCESS;
4042 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4043 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
4044 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4045 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4046 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304047 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304048 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
4049 auto rc = encode_verify_complete_resp(instanceId, completionCode,
4050 responseMsg1, sizeof(completionCode));
4051 EXPECT_EQ(rc, PLDM_SUCCESS);
4052 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
4053
4054 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4055 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
4056 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4057 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4058 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304059 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304060 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
4061 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4062 responseMsg2, sizeof(completionCode));
4063 EXPECT_EQ(rc, PLDM_SUCCESS);
4064 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
4065}
4066
4067TEST(VerifyComplete, errorPathEncodeResponse)
4068{
4069 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
4070 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304071 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304072 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
4073 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4074 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4075
4076 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4077 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4078}
4079
4080TEST(ApplyComplete, goodPathDecodeRequest)
4081{
4082 constexpr uint8_t applyResult1 =
4083 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
4084 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
4085 constexpr std::bitset<16> compActivationModification1{0x30};
4086 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4087 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
4088 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304089 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304090 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4091 uint8_t outApplyResult = 0;
4092 bitfield16_t outCompActivationModification{};
4093 auto rc = decode_apply_complete_req(
4094 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
4095 &outCompActivationModification);
4096 EXPECT_EQ(rc, PLDM_SUCCESS);
4097 EXPECT_EQ(outApplyResult, applyResult1);
4098 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
4099
4100 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
4101 constexpr std::bitset<16> compActivationModification2{};
4102 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4103 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4104 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304105 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304106 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4107 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4108 &outApplyResult,
4109 &outCompActivationModification);
4110 EXPECT_EQ(rc, PLDM_SUCCESS);
4111 EXPECT_EQ(outApplyResult, applyResult2);
4112 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
4113}
4114
4115TEST(ApplyComplete, errorPathDecodeRequest)
4116{
4117 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
4118 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304119 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304120 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4121 uint8_t outApplyResult = 0;
4122 bitfield16_t outCompActivationModification{};
4123
4124 auto rc = decode_apply_complete_req(
4125 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
4126 &outCompActivationModification);
4127 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4128
4129 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4130 nullptr, &outCompActivationModification);
4131 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4132
4133 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4134 &outApplyResult, nullptr);
4135 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4136
4137 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
4138 &outCompActivationModification);
4139 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4140
4141 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4142 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
4143 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304144 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304145 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4146 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4147 &outApplyResult,
4148 &outCompActivationModification);
4149 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4150}
4151
4152TEST(ApplyComplete, goodPathEncodeResponse)
4153{
4154 constexpr uint8_t instanceId = 6;
4155 constexpr uint8_t completionCode = PLDM_SUCCESS;
4156 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4157 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
4158 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4159 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4160 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304161 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304162 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
4163 auto rc = encode_apply_complete_resp(instanceId, completionCode,
4164 responseMsg1, sizeof(completionCode));
4165 EXPECT_EQ(rc, PLDM_SUCCESS);
4166 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
4167
4168 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4169 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
4170 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4171 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4172 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304173 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304174 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
4175 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4176 responseMsg2, sizeof(completionCode));
4177 EXPECT_EQ(rc, PLDM_SUCCESS);
4178 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
4179}
4180
4181TEST(ApplyComplete, errorPathEncodeResponse)
4182{
4183 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
4184 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304185 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304186 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
4187 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4188 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4189
4190 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4191 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4192}
4193
4194TEST(ActivateFirmware, goodPathEncodeRequest)
4195{
4196 constexpr uint8_t instanceId = 7;
4197
4198 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304199 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304200 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4201
4202 auto rc = encode_activate_firmware_req(
4203 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
4204 sizeof(pldm_activate_firmware_req));
4205 EXPECT_EQ(rc, PLDM_SUCCESS);
4206
4207 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004208 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304209 EXPECT_EQ(request, outRequest);
4210}
4211
4212TEST(ActivateFirmware, errorPathEncodeRequest)
4213{
4214 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304215 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304216 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4217
4218 auto rc = encode_activate_firmware_req(
4219 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
4220 sizeof(pldm_activate_firmware_req));
4221 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4222
4223 rc = encode_activate_firmware_req(
4224 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
4225 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4226
4227 rc = encode_activate_firmware_req(0, 2, requestMsg,
4228 sizeof(pldm_activate_firmware_req));
4229 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4230}
4231
4232TEST(ActivateFirmware, goodPathDecodeResponse)
4233{
4234 constexpr uint16_t estimatedTimeForActivation100s = 100;
4235 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4236 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
4237 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304238 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304239 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
4240
4241 uint8_t completionCode = 0;
4242 uint16_t estimatedTimeForActivation = 0;
4243
4244 auto rc = decode_activate_firmware_resp(
4245 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
4246 &estimatedTimeForActivation);
4247
4248 EXPECT_EQ(rc, PLDM_SUCCESS);
4249 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4250 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
4251
4252 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4253 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
4254 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304255 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304256 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
4257
4258 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
4259 &completionCode,
4260 &estimatedTimeForActivation);
4261
4262 EXPECT_EQ(rc, PLDM_SUCCESS);
4263 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
4264}
4265
4266TEST(ActivateFirmware, errorPathDecodeResponse)
4267{
4268 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4269 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4270 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304271 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304272 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
4273
4274 uint8_t completionCode = 0;
4275 uint16_t estimatedTimeForActivation = 0;
4276
4277 auto rc = decode_activate_firmware_resp(
4278 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
4279 &estimatedTimeForActivation);
4280 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4281
4282 rc = decode_activate_firmware_resp(responseMsg,
4283 sizeof(pldm_activate_firmware_resp),
4284 nullptr, &estimatedTimeForActivation);
4285 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4286
4287 rc = decode_activate_firmware_resp(responseMsg,
4288 sizeof(pldm_activate_firmware_resp),
4289 &completionCode, nullptr);
4290 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4291
4292 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
4293 &estimatedTimeForActivation);
4294 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4295
4296 rc = decode_activate_firmware_resp(
4297 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
4298 &estimatedTimeForActivation);
4299 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4300}
4301
4302TEST(GetStatus, goodPathEncodeRequest)
4303{
4304 constexpr uint8_t instanceId = 8;
4305 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304306 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304307 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4308
4309 auto rc = encode_get_status_req(instanceId, requestMsg,
4310 PLDM_GET_STATUS_REQ_BYTES);
4311 EXPECT_EQ(rc, PLDM_SUCCESS);
4312
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004313 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304314 EXPECT_EQ(request, outRequest);
4315}
4316
4317TEST(GetStatus, errorPathEncodeRequest)
4318{
4319 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304320 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304321 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4322
4323 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4324 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4325
4326 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4327 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4328}
4329
4330TEST(GetStatus, goodPathDecodeResponse)
4331{
4332 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4333 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4334 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4335 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4336 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304337 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304338 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4339
4340 uint8_t completionCode = 0;
4341 uint8_t currentState = 0;
4342 uint8_t previousState = 0;
4343 uint8_t auxState = 0;
4344 uint8_t auxStateStatus = 0;
4345 uint8_t progressPercent = 0;
4346 uint8_t reasonCode = 0;
4347 bitfield32_t updateOptionFlagsEnabled{0};
4348
4349 auto rc = decode_get_status_resp(
4350 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4351 &currentState, &previousState, &auxState, &auxStateStatus,
4352 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4353
4354 EXPECT_EQ(rc, PLDM_SUCCESS);
4355 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4356 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4357 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4358 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4359 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4360 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4361 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4362 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4363
4364 // Bit position 0 - Force update of component – FD will perform a force
4365 // update of the component.
4366 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4367 constexpr uint8_t progressPercent2 = 50;
4368 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4369 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4370 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4371 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304372 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304373 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4374
4375 rc = decode_get_status_resp(
4376 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4377 &currentState, &previousState, &auxState, &auxStateStatus,
4378 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4379
4380 EXPECT_EQ(rc, PLDM_SUCCESS);
4381 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4382 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4383 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4384 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4385 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4386 EXPECT_EQ(progressPercent, progressPercent2);
4387 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4388 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4389
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004390#ifdef LIBPLDM_API_TESTING
4391 /* Check the roundtrip */
4392 PLDM_MSG_DEFINE_P(enc, 1000);
4393 size_t enc_payload_len = 1000;
4394 const struct pldm_get_status_resp status_enc = {
4395 .completion_code = PLDM_SUCCESS,
4396 .current_state = currentState,
4397 .previous_state = previousState,
4398 .aux_state = auxState,
4399 .aux_state_status = auxStateStatus,
4400 .progress_percent = progressPercent,
4401 .reason_code = reasonCode,
4402 .update_option_flags_enabled = updateOptionFlagsEnabled,
4403 };
4404 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4405 &enc_payload_len);
4406 EXPECT_EQ(rc, PLDM_SUCCESS);
4407 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4408 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4409 getStatusResponse2.end(), enc_buf + hdrSize));
4410 check_response(enc, PLDM_GET_STATUS);
4411#endif
4412
4413 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304414 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4415 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4416 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304417 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304418 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4419 rc = decode_get_status_resp(
4420 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4421 &currentState, &previousState, &auxState, &auxStateStatus,
4422 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4423 EXPECT_EQ(rc, PLDM_SUCCESS);
4424 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4425}
4426
4427TEST(GetStatus, errorPathDecodeResponse)
4428{
4429 uint8_t completionCode = 0;
4430 uint8_t currentState = 0;
4431 uint8_t previousState = 0;
4432 uint8_t auxState = 0;
4433 uint8_t auxStateStatus = 0;
4434 uint8_t progressPercent = 0;
4435 uint8_t reasonCode = 0;
4436 bitfield32_t updateOptionFlagsEnabled{0};
4437
4438 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4439 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304440 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304441 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4442
4443 auto rc = decode_get_status_resp(
4444 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4445 &currentState, &previousState, &auxState, &auxStateStatus,
4446 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4447 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4448
4449 rc = decode_get_status_resp(
4450 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4451 &currentState, &previousState, &auxState, &auxStateStatus,
4452 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4453 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4454
4455 rc = decode_get_status_resp(
4456 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4457 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4458 &reasonCode, &updateOptionFlagsEnabled);
4459 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4460
4461 rc = decode_get_status_resp(
4462 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4463 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4464 &reasonCode, &updateOptionFlagsEnabled);
4465 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4466
4467 rc = decode_get_status_resp(
4468 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4469 &currentState, &previousState, nullptr, &auxStateStatus,
4470 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4471 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4472
4473 rc = decode_get_status_resp(
4474 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4475 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4476 &reasonCode, &updateOptionFlagsEnabled);
4477 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4478
4479 rc = decode_get_status_resp(
4480 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4481 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4482 &reasonCode, &updateOptionFlagsEnabled);
4483 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4484
4485 rc = decode_get_status_resp(
4486 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4487 &currentState, &previousState, &auxState, &auxStateStatus,
4488 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4489 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4490
4491 rc = decode_get_status_resp(
4492 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4493 &currentState, &previousState, &auxState, &auxStateStatus,
4494 &progressPercent, &reasonCode, nullptr);
4495 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4496
4497 rc = decode_get_status_resp(
4498 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4499 &currentState, &previousState, &auxState, &auxStateStatus,
4500 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4501 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4502
4503 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4504 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4506 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304507 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304508 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4509 rc = decode_get_status_resp(
4510 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4511 &currentState, &previousState, &auxState, &auxStateStatus,
4512 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4513 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4514
4515 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4516 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4518 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304519 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304520 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4521 rc = decode_get_status_resp(
4522 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4523 &currentState, &previousState, &auxState, &auxStateStatus,
4524 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4525 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4526
4527 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4528 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4530 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304531 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304532 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4533 rc = decode_get_status_resp(
4534 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4535 &currentState, &previousState, &auxState, &auxStateStatus,
4536 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4537 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4538
4539 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4540 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4542 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304543 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304544 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4545 rc = decode_get_status_resp(
4546 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4547 &currentState, &previousState, &auxState, &auxStateStatus,
4548 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4549 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4550
4551 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4552 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004553 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304554 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304555 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304556 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4557 rc = decode_get_status_resp(
4558 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4559 &currentState, &previousState, &auxState, &auxStateStatus,
4560 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4561 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4562
4563 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4564 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4565 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4566 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304567 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304568 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4569 rc = decode_get_status_resp(
4570 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4571 &currentState, &previousState, &auxState, &auxStateStatus,
4572 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4573 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4574
4575 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4576 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004577 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304578 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304579 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304580 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4581 rc = decode_get_status_resp(
4582 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4583 &currentState, &previousState, &auxState, &auxStateStatus,
4584 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4585 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4586
4587 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4588 // IDLE
4589 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4590 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4591 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4592 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304593 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304594 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4595 rc = decode_get_status_resp(
4596 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4597 &currentState, &previousState, &auxState, &auxStateStatus,
4598 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4599 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4600}
4601
4602TEST(CancelUpdateComponent, goodPathEncodeRequest)
4603{
4604 constexpr uint8_t instanceId = 9;
4605 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304606 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304607 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4608
4609 auto rc = encode_cancel_update_component_req(
4610 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4611 EXPECT_EQ(rc, PLDM_SUCCESS);
4612
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004613 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304614 EXPECT_EQ(request, outRequest);
4615}
4616
4617TEST(CancelUpdateComponent, errorPathEncodeRequest)
4618{
4619 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304620 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304621 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4622
4623 auto rc = encode_cancel_update_component_req(
4624 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4625 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4626
4627 rc = encode_cancel_update_component_req(
4628 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4629 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4630}
4631
4632TEST(CancelUpdateComponent, testGoodDecodeResponse)
4633{
4634 uint8_t completionCode = 0;
4635 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4636 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304637 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304638 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4639 cancelUpdateComponentResponse1.data());
4640 auto rc = decode_cancel_update_component_resp(
4641 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4642 &completionCode);
4643 EXPECT_EQ(rc, PLDM_SUCCESS);
4644 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4645
4646 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4647 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304648 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304649 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4650 cancelUpdateComponentResponse2.data());
4651 rc = decode_cancel_update_component_resp(
4652 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4653 &completionCode);
4654 EXPECT_EQ(rc, PLDM_SUCCESS);
4655 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4656}
4657
4658TEST(CancelUpdateComponent, testBadDecodeResponse)
4659{
4660 uint8_t completionCode = 0;
4661 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4662 0x00, 0x00, 0x00};
4663 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304664 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304665 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4666
4667 auto rc = decode_cancel_update_component_resp(
4668 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4669 &completionCode);
4670 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4671
4672 rc = decode_cancel_update_component_resp(
4673 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4674 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4675
4676 rc = decode_cancel_update_component_resp(
4677 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4678 &completionCode);
4679 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4680}
4681
4682TEST(CancelUpdate, goodPathEncodeRequest)
4683{
4684 constexpr uint8_t instanceId = 10;
4685 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304686 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304687 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4688
4689 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4690 PLDM_CANCEL_UPDATE_REQ_BYTES);
4691 EXPECT_EQ(rc, PLDM_SUCCESS);
4692
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004693 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304694 EXPECT_EQ(request, outRequest);
4695}
4696
4697TEST(CancelUpdate, errorPathEncodeRequest)
4698{
4699 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304700 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304701 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4702
4703 auto rc =
4704 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4705 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4706
4707 rc = encode_cancel_update_req(0, requestMsg,
4708 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4709 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4710}
4711
4712TEST(CancelUpdate, goodPathDecodeResponse)
4713{
4714 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4715 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4716 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4718 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304719 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304720 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4721 uint8_t completionCode = 0;
4722 bool8_t nonFunctioningComponentIndication = 0;
4723 bitfield64_t nonFunctioningComponentBitmap{0};
4724 auto rc = decode_cancel_update_resp(
4725 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4726 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4727 EXPECT_EQ(rc, PLDM_SUCCESS);
4728 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4729 EXPECT_EQ(nonFunctioningComponentIndication,
4730 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4731 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4732 nonFunctioningComponentBitmap1);
4733
4734 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4735 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4736 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4738 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304739 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304740 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4741 rc = decode_cancel_update_resp(
4742 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4743 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4744 EXPECT_EQ(rc, PLDM_SUCCESS);
4745 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4746 EXPECT_EQ(nonFunctioningComponentIndication,
4747 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4748 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4749 nonFunctioningComponentBitmap2);
4750
4751 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4752 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4753 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304754 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304755 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4756 rc = decode_cancel_update_resp(
4757 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4758 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4759 EXPECT_EQ(rc, PLDM_SUCCESS);
4760 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4761}
4762
4763TEST(CancelUpdate, errorPathDecodeResponse)
4764{
4765 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4766 0x00};
4767 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304768 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304769 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4770 uint8_t completionCode = 0;
4771 bool8_t nonFunctioningComponentIndication = 0;
4772 bitfield64_t nonFunctioningComponentBitmap{0};
4773
4774 auto rc = decode_cancel_update_resp(
4775 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4776 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4777 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4778
4779 rc = decode_cancel_update_resp(
4780 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4781 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4782 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4783
4784 rc = decode_cancel_update_resp(
4785 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4786 nullptr, &nonFunctioningComponentBitmap);
4787 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4788
4789 rc = decode_cancel_update_resp(
4790 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4791 &nonFunctioningComponentIndication, nullptr);
4792 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4793
4794 rc = decode_cancel_update_resp(
4795 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4796 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4797 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4798
4799 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4800 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4801 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304802 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304803 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4804 rc = decode_cancel_update_resp(
4805 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4806 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4807 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4808
4809 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4810 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4812 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304813 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304814 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4815 rc = decode_cancel_update_resp(
4816 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4817 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4818 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4819}
Andrew Jeffery2613c272025-03-12 14:15:41 +10304820
4821#ifdef LIBPLDM_API_TESTING
4822TEST(DecodePldmFirmwareUpdatePackage, badArguments)
4823{
4824 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
4825 pldm_package_header_information_pad hdr;
4826 struct pldm_package_iter iter;
4827 uint8_t data;
4828 int rc;
4829
4830 rc = decode_pldm_firmware_update_package(nullptr, 0, &pin, &hdr, &iter);
4831 EXPECT_EQ(rc, -EINVAL);
4832
4833 rc = decode_pldm_firmware_update_package(&data, sizeof(data), nullptr, &hdr,
4834 &iter);
4835 EXPECT_EQ(rc, -EINVAL);
4836
4837 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, nullptr,
4838 &iter);
4839 EXPECT_EQ(rc, -EINVAL);
4840
4841 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4842 nullptr);
4843 EXPECT_EQ(rc, -EINVAL);
4844}
4845#endif
4846
4847#ifdef LIBPLDM_API_TESTING
4848TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinVersion)
4849{
4850 const struct pldm_package_format_pin pin = {
4851 .meta =
4852 {
4853 .magic = 0,
4854 .version = UINT8_MAX,
4855 },
4856 .format =
4857 {
4858 .identifier = {0},
4859 .revision = 0,
4860 },
4861 };
4862
4863 pldm_package_header_information_pad hdr;
4864 struct pldm_package_iter iter;
4865 uint8_t data = 0;
4866 int rc;
4867
4868 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4869 &iter);
4870 EXPECT_EQ(rc, -ENOTSUP);
4871}
4872#endif
4873
4874#ifdef LIBPLDM_API_TESTING
4875TEST(DecodePldmFirmwareUpdatePackage, badPinRevision)
4876{
4877 const struct pldm_package_format_pin lowPin = {
4878 .meta =
4879 {
4880 .magic = 0,
4881 .version = 0,
4882 },
4883 .format =
4884 {
4885 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4886 .revision = 0,
4887 },
4888 };
4889
4890 const struct pldm_package_format_pin highPin = {
4891 .meta =
4892 {
4893 .magic = 0,
4894 .version = 0,
4895 },
4896 .format =
4897 {
4898 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4899 .revision = 3,
4900 },
4901 };
4902
4903 pldm_package_header_information_pad hdr;
4904 struct pldm_package_iter iter;
4905 uint8_t data = 0;
4906 int rc;
4907
4908 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4909 &iter);
4910 EXPECT_EQ(rc, -EINVAL);
4911
4912 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4913 &hdr, &iter);
4914 EXPECT_EQ(rc, -ENOTSUP);
4915}
4916#endif
4917
4918#ifdef LIBPLDM_API_TESTING
4919TEST(DecodePldmFirmwareUpdatePackage, badPinMagic)
4920{
4921 const struct pldm_package_format_pin lowPin = {
4922 .meta =
4923 {
4924 .magic = 0,
4925 .version = 0,
4926 },
4927 .format =
4928 {
4929 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4930 .revision = 2,
4931 },
4932 };
4933
4934 const struct pldm_package_format_pin highPin = {
4935 .meta =
4936 {
4937 .magic = UINT32_MAX,
4938 .version = 0,
4939 },
4940 .format =
4941 {
4942 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4943 .revision = 2,
4944 },
4945 };
4946
4947 pldm_package_header_information_pad hdr;
4948 struct pldm_package_iter iter;
4949 uint8_t data = 0;
4950 int rc;
4951
4952 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4953 &iter);
4954 EXPECT_EQ(rc, -EINVAL);
4955
4956 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4957 &hdr, &iter);
4958 EXPECT_EQ(rc, -EINVAL);
4959}
4960#endif
4961
4962#ifdef LIBPLDM_API_TESTING
4963TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinIdentifier)
4964{
4965 const struct pldm_package_format_pin pin = {
4966 .meta =
4967 {
4968 .magic =
4969 LIBPLDM_SIZEAT(struct pldm__package_header_information,
4970 package) +
4971 LIBPLDM_SIZEAT(
4972 struct pldm_package_firmware_device_id_record,
4973 firmware_device_package_data) +
4974 LIBPLDM_SIZEAT(struct pldm_descriptor, descriptor_data) +
4975 LIBPLDM_SIZEAT(
4976 struct pldm_package_downstream_device_id_record,
4977 package_data) +
4978 LIBPLDM_SIZEAT(
4979 struct pldm_package_component_image_information,
4980 component_version_string) +
4981 LIBPLDM_SIZEAT(struct pldm_package_iter, infos),
4982 .version = 0,
4983 },
4984 .format =
4985 {
4986 .identifier = {0},
4987 .revision = PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR02H,
4988 },
4989 };
4990
4991 pldm_package_header_information_pad hdr;
4992 struct pldm_package_iter iter;
4993 uint8_t data = 0;
4994 int rc;
4995
4996 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4997 &iter);
4998 EXPECT_EQ(rc, -ENOTSUP);
4999}
5000#endif
5001
5002#ifdef LIBPLDM_API_TESTING
5003TEST(DecodePldmFirmwareUpdatePackage, oldConsumer)
5004{
5005 /* Package format revision 2 header */
5006 const std::array<uint8_t, 150> package{
5007 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5008 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5009 0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5010 0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5011 };
5012
5013 /* Package format revision 1 consumer */
5014 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5015
5016 pldm_package_header_information_pad hdr;
5017 struct pldm_package_iter iter;
5018 int rc;
5019
5020 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5021 &pin, &hdr, &iter);
5022 EXPECT_EQ(rc, -ENOTSUP);
5023}
5024#endif
5025
5026#ifdef LIBPLDM_API_TESTING
5027TEST(DecodePldmFirmwareUpdatePackage, v1h1fd1fdd1cii)
5028{
5029 const std::array<uint8_t, 102> package{
5030 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5031 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5032 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5033 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5034
5035 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5036 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c,
5037 0x01, 0x00, 0x00,
5038
5039 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5040 0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5041 0x01, 0x04, 'v', '0', '.', '2', 0x00, 0x00, 0x00, 0x00,
5042
5043 0xb5, 0x3f, 0xf6, 0x6a,
5044
5045 0x5a,
5046 };
5047
5048 struct pldm_package_downstream_device_id_record ddrec;
5049 struct pldm_package_component_image_information info;
5050 struct pldm_package_firmware_device_id_record fdrec;
5051 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5052 pldm_package_header_information_pad hdr;
5053 struct pldm_package_iter iter;
5054 int nr_fdrec_desc = 0;
5055 int nr_ddrec_desc = 0;
5056 int nr_fdrec = 0;
5057 int nr_ddrec = 0;
5058 int nr_infos = 0;
5059 int rc;
5060
5061 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5062 &pin, &hdr, &iter);
5063 ASSERT_EQ(rc, 0);
5064
5065 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5066 hdr.package_header_identifier,
5067 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5068 0);
5069 EXPECT_EQ(hdr.package_header_format_revision, 1);
5070
5071 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5072 0x16, 0x03, 0x00, 0x00, 0x00,
5073 0x00, 0x76, 0x02};
5074 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5075 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5076 timestamp.size()),
5077 0);
5078
5079 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5080 EXPECT_EQ(hdr.package_version_string_type, 1);
5081 ASSERT_EQ(hdr.package_version_string.length, 4);
5082 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5083 hdr.package_version_string.length),
5084 0);
5085 EXPECT_NE(hdr.areas.ptr, nullptr);
5086 EXPECT_NE(hdr.areas.length, 0);
5087 EXPECT_NE(hdr.package.ptr, nullptr);
5088 EXPECT_NE(hdr.package.length, 0);
5089
5090 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5091 {
5092 struct pldm_descriptor desc;
5093
5094 EXPECT_EQ(fdrec.descriptor_count, 1);
5095 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5096 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5097 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5098 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5099 fdrec.component_image_set_version_string.length),
5100 0);
5101 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5102 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5103 EXPECT_NE(fdrec.record_descriptors.length, 0);
5104 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5105 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5106
5107 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5108 desc, rc)
5109 {
5110 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5111
5112 EXPECT_EQ(desc.descriptor_type, 1);
5113 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5114 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5115 sizeof(iana_pen_dmtf)),
5116 0);
5117
5118 nr_fdrec_desc++;
5119 }
5120 ASSERT_EQ(rc, 0);
5121
5122 nr_fdrec++;
5123 }
5124 ASSERT_EQ(rc, 0);
5125
5126 EXPECT_EQ(nr_fdrec, 1);
5127 EXPECT_EQ(nr_fdrec_desc, 1);
5128
5129 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5130 {
5131 struct pldm_descriptor desc;
5132
5133 EXPECT_EQ(ddrec.descriptor_count, 1);
5134 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5135 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5136 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5137 EXPECT_EQ(
5138 memcmp("v1.0",
5139 ddrec.self_contained_activation_min_version_string.ptr,
5140 ddrec.self_contained_activation_min_version_string.length),
5141 0);
5142 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5143 0);
5144 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5145 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5146 EXPECT_NE(ddrec.record_descriptors.length, 0);
5147 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5148 EXPECT_EQ(ddrec.package_data.length, 0);
5149
5150 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5151 desc, rc)
5152 {
5153 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5154
5155 EXPECT_EQ(desc.descriptor_type, 1);
5156 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5157 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5158 sizeof(iana_pen_dmtf)),
5159 0);
5160
5161 nr_ddrec_desc++;
5162 }
5163 ASSERT_EQ(rc, 0);
5164
5165 nr_ddrec++;
5166 }
5167 ASSERT_EQ(rc, 0);
5168
5169 EXPECT_EQ(nr_ddrec, 0);
5170 EXPECT_EQ(nr_ddrec_desc, 0);
5171
5172 static const pldm_package_component_image_information expected_info{
Carter Chenf72cf6f2025-06-24 15:34:49 +08005173 0x000a, 0x0000, 0xffffffff, {0}, {1},
5174 {nullptr, 1}, 0x01, {nullptr, 0}, {nullptr, 0}};
Andrew Jeffery2613c272025-03-12 14:15:41 +10305175
5176 foreach_pldm_package_component_image_information(iter, info, rc)
5177 {
5178 EXPECT_EQ(info.component_classification,
5179 expected_info.component_classification);
5180 EXPECT_EQ(info.component_identifier,
5181 expected_info.component_identifier);
5182 EXPECT_EQ(info.component_comparison_stamp,
5183 expected_info.component_comparison_stamp);
5184 EXPECT_EQ(info.component_options.value,
5185 expected_info.component_options.value);
5186 EXPECT_EQ(info.requested_component_activation_method.value,
5187 expected_info.requested_component_activation_method.value);
5188 EXPECT_NE(nullptr, info.component_image.ptr);
5189 EXPECT_EQ(info.component_image.length,
5190 expected_info.component_image.length);
5191 EXPECT_EQ(info.component_version_string_type,
5192 expected_info.component_version_string_type);
5193 ASSERT_EQ(info.component_version_string.length, 4);
5194 EXPECT_EQ(memcmp("v0.2", info.component_version_string.ptr,
5195 info.component_version_string.length),
5196 0);
5197
5198 nr_infos++;
5199 }
5200 ASSERT_EQ(rc, 0);
5201
5202 EXPECT_EQ(nr_infos, 1);
5203}
5204#endif
5205
5206#ifdef LIBPLDM_API_TESTING
5207TEST(DecodePldmFirmwareUpdatePackage, v2h1fd1fdd1dd1ddd2cii)
5208{
5209 const std::array<uint8_t, 150> package{
5210 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5211 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5212 0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5213 0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5214
5215 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5216 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
5217 0x00, 0x9c, 0x01, 0x00, 0x00,
5218
5219 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5220 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
5221 0x00, 0x9c, 0x01, 0x00, 0x00,
5222
5223 0x02, 0x00,
5224
5225 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5226 0x01, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5227 0x01, 0x04, 'v', '0', '.', '2',
5228
5229 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5230 0x01, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5231 0x01, 0x04, 'v', '2', '.', '0',
5232
5233 0xd3, 0x5c, 0x1c, 0x8a,
5234
5235 0x5a,
5236
5237 0xa5,
5238 };
5239 struct pldm_package_downstream_device_id_record ddrec;
5240 struct pldm_package_component_image_information info;
5241 struct pldm_package_firmware_device_id_record fdrec;
5242 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5243 pldm_package_header_information_pad hdr;
5244 struct pldm_package_iter iter;
5245 int nr_fdrec_desc = 0;
5246 int nr_ddrec_desc = 0;
5247 int nr_fdrec = 0;
5248 int nr_ddrec = 0;
5249 int nr_infos = 0;
5250 int rc;
5251
5252 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5253 &pin, &hdr, &iter);
5254 ASSERT_EQ(rc, 0);
5255
5256 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.data(),
5257 hdr.package_header_identifier,
5258 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.size()),
5259 0);
5260 EXPECT_EQ(hdr.package_header_format_revision, 2);
5261
5262 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5263 0x16, 0x03, 0x00, 0x00, 0x00,
5264 0x00, 0x76, 0x02};
5265 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5266 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5267 timestamp.size()),
5268 0);
5269
5270 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5271 EXPECT_EQ(hdr.package_version_string_type, 1);
5272 ASSERT_EQ(hdr.package_version_string.length, 4);
5273 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5274 hdr.package_version_string.length),
5275 0);
5276 EXPECT_NE(hdr.areas.ptr, nullptr);
5277 EXPECT_NE(hdr.areas.length, 0);
5278 EXPECT_NE(hdr.package.ptr, nullptr);
5279 EXPECT_NE(hdr.package.length, 0);
5280
5281 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5282 {
5283 struct pldm_descriptor desc;
5284
5285 EXPECT_EQ(fdrec.descriptor_count, 1);
5286 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5287 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5288 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5289 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5290 fdrec.component_image_set_version_string.length),
5291 0);
5292 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5293 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5294 EXPECT_NE(fdrec.record_descriptors.length, 0);
5295 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5296 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5297
5298 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5299 desc, rc)
5300 {
5301 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5302
5303 EXPECT_EQ(desc.descriptor_type, 1);
5304 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5305 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5306 sizeof(iana_pen_dmtf)),
5307 0);
5308
5309 nr_fdrec_desc++;
5310 }
5311 ASSERT_EQ(rc, 0);
5312
5313 nr_fdrec++;
5314 }
5315 ASSERT_EQ(rc, 0);
5316
5317 EXPECT_EQ(nr_fdrec, 1);
5318 EXPECT_EQ(nr_fdrec_desc, 1);
5319
5320 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5321 {
5322 struct pldm_descriptor desc;
5323
5324 EXPECT_EQ(ddrec.descriptor_count, 1);
5325 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5326 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5327 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5328 EXPECT_EQ(
5329 memcmp("v1.0",
5330 ddrec.self_contained_activation_min_version_string.ptr,
5331 ddrec.self_contained_activation_min_version_string.length),
5332 0);
5333 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5334 0);
5335 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5336 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5337 EXPECT_NE(ddrec.record_descriptors.length, 0);
5338 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5339 EXPECT_EQ(ddrec.package_data.length, 0);
5340
5341 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5342 desc, rc)
5343 {
5344 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5345
5346 EXPECT_EQ(desc.descriptor_type, 1);
5347 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5348 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5349 sizeof(iana_pen_dmtf)),
5350 0);
5351
5352 nr_ddrec_desc++;
5353 }
5354 ASSERT_EQ(rc, 0);
5355
5356 nr_ddrec++;
5357 }
5358 ASSERT_EQ(rc, 0);
5359
5360 EXPECT_EQ(nr_ddrec, 1);
5361 EXPECT_EQ(nr_ddrec_desc, 1);
5362
5363 static const std::array<const char*, 2> component_versions = {
5364 "v0.2",
5365 "v2.0",
5366 };
5367 static const std::array<pldm_package_component_image_information, 2>
5368 expected_infos{{{0x000a,
5369 0x0000,
5370 0xffffffff,
5371 {0},
5372 {1},
5373 {nullptr, 1},
5374 0x01,
Carter Chenf72cf6f2025-06-24 15:34:49 +08005375 {nullptr, 0},
Andrew Jeffery2613c272025-03-12 14:15:41 +10305376 {nullptr, 0}},
5377 {0x000a,
5378 0x0000,
5379 0xffffffff,
5380 {0},
5381 {1},
5382 {nullptr, 1},
5383 0x01,
Carter Chenf72cf6f2025-06-24 15:34:49 +08005384 {nullptr, 0},
Andrew Jeffery2613c272025-03-12 14:15:41 +10305385 {nullptr, 0}}}};
5386 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5387
5388 foreach_pldm_package_component_image_information(iter, info, rc)
5389 {
5390 const struct pldm_package_component_image_information* expected;
5391 const char* version;
5392 uint8_t image;
5393
5394 expected = &expected_infos.at(nr_infos);
5395 version = component_versions.at(nr_infos);
5396 image = expected_images.at(nr_infos);
5397
5398 EXPECT_EQ(info.component_classification,
5399 expected->component_classification);
5400 EXPECT_EQ(info.component_identifier, expected->component_identifier);
5401 EXPECT_EQ(info.component_comparison_stamp,
5402 expected->component_comparison_stamp);
5403 EXPECT_EQ(info.component_options.value,
5404 expected->component_options.value);
5405 EXPECT_EQ(info.requested_component_activation_method.value,
5406 expected->requested_component_activation_method.value);
5407 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5408 EXPECT_EQ(info.component_image.length,
5409 expected->component_image.length);
5410 EXPECT_EQ(*info.component_image.ptr, image);
5411 EXPECT_EQ(info.component_version_string_type,
5412 expected->component_version_string_type);
5413 ASSERT_EQ(info.component_version_string.length, 4);
5414 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5415 info.component_version_string.length),
5416 0);
5417
5418 nr_infos++;
5419 }
5420 ASSERT_EQ(rc, 0);
5421
5422 EXPECT_EQ(nr_infos, 2);
5423}
5424#endif
Carter Chenf72cf6f2025-06-24 15:34:49 +08005425
5426#ifdef LIBPLDM_API_TESTING
5427TEST(DecodePldmFirmwareUpdatePackage, v3h1fd1fdd1dd1ddd2cii)
5428{
5429 const std::array<uint8_t, 166> package{
5430 0x31, 0x19, 0xce, 0x2f, 0xe8, 0x0a, 0x4a, 0x99, 0xaf, 0x6d, 0x46, 0xf8,
5431 0xb1, 0x21, 0xf6, 0xbf, 0x03, 0xA4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5432 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5433 't', 'e', 's', 't',
5434
5435 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5436 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5437 0x00,
5438
5439 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5440 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5441 0x00,
5442
5443 0x02, 0x00,
5444
5445 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5446 0xA4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '0',
5447 '.', '2', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5448
5449 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5450 0xA5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '2',
5451 '.', '0', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5452
5453 0xed, 0x9d, 0x97, 0x7a,
5454
5455 0x5a,
5456
5457 0xa5,
5458
5459 };
5460
5461 struct pldm_package_downstream_device_id_record ddrec;
5462 struct pldm_package_component_image_information info;
5463 struct pldm_package_firmware_device_id_record fdrec;
5464 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR03H(pin);
5465 pldm_package_header_information_pad hdr;
5466 struct pldm_package_iter iter;
5467 int nr_fdrec_desc = 0;
5468 int nr_ddrec_desc = 0;
5469 int nr_fdrec = 0;
5470 int nr_ddrec = 0;
5471 int nr_infos = 0;
5472 int rc;
5473
5474 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5475 &pin, &hdr, &iter);
5476 ASSERT_EQ(rc, 0);
5477
5478 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.data(),
5479 hdr.package_header_identifier,
5480 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.size()),
5481 0);
5482 EXPECT_EQ(hdr.package_header_format_revision, 3);
5483
5484 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5485 0x16, 0x03, 0x00, 0x00, 0x00,
5486 0x00, 0x76, 0x02};
5487 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5488 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5489 timestamp.size()),
5490 0);
5491
5492 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5493 EXPECT_EQ(hdr.package_version_string_type, 1);
5494 ASSERT_EQ(hdr.package_version_string.length, 4);
5495 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5496 hdr.package_version_string.length),
5497 0);
5498 EXPECT_NE(hdr.areas.ptr, nullptr);
5499 EXPECT_NE(hdr.areas.length, 0);
5500 EXPECT_NE(hdr.package.ptr, nullptr);
5501 EXPECT_NE(hdr.package.length, 0);
5502
5503 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5504 {
5505 struct pldm_descriptor desc;
5506
5507 EXPECT_EQ(fdrec.descriptor_count, 1);
5508 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5509 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5510 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5511 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5512 fdrec.component_image_set_version_string.length),
5513 0);
5514 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5515 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5516 EXPECT_NE(fdrec.record_descriptors.length, 0);
5517 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5518 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5519
5520 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5521 desc, rc)
5522 {
5523 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5524
5525 EXPECT_EQ(desc.descriptor_type, 1);
5526 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5527 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5528 sizeof(iana_pen_dmtf)),
5529 0);
5530
5531 nr_fdrec_desc++;
5532 }
5533 ASSERT_EQ(rc, 0);
5534
5535 nr_fdrec++;
5536 }
5537 ASSERT_EQ(rc, 0);
5538
5539 EXPECT_EQ(nr_fdrec, 1);
5540 EXPECT_EQ(nr_fdrec_desc, 1);
5541
5542 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5543 {
5544 struct pldm_descriptor desc;
5545
5546 EXPECT_EQ(ddrec.descriptor_count, 1);
5547 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5548 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5549 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5550 EXPECT_EQ(
5551 memcmp("v1.0",
5552 ddrec.self_contained_activation_min_version_string.ptr,
5553 ddrec.self_contained_activation_min_version_string.length),
5554 0);
5555 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5556 0);
5557 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5558 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5559 EXPECT_NE(ddrec.record_descriptors.length, 0);
5560 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5561 EXPECT_EQ(ddrec.package_data.length, 0);
5562
5563 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5564 desc, rc)
5565 {
5566 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5567
5568 EXPECT_EQ(desc.descriptor_type, 1);
5569 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5570 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5571 sizeof(iana_pen_dmtf)),
5572 0);
5573
5574 nr_ddrec_desc++;
5575 }
5576 ASSERT_EQ(rc, 0);
5577
5578 nr_ddrec++;
5579 }
5580 ASSERT_EQ(rc, 0);
5581
5582 EXPECT_EQ(nr_ddrec, 1);
5583 EXPECT_EQ(nr_ddrec_desc, 1);
5584
5585 static const std::array<const char*, 2> component_versions = {
5586 "v0.2",
5587 "v2.0",
5588 };
5589
5590 static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
5591 0x78};
5592
5593 static const std::array<pldm_package_component_image_information, 2>
5594 expected_infos{
5595 {{0x000a,
5596 0x0000,
5597 0xffffffff,
5598 {0},
5599 {1},
5600 {nullptr, 1},
5601 0x01,
5602 {nullptr, 0},
5603 {expected_opaque_data.data(), expected_opaque_data.size()}},
5604 {0x000a,
5605 0x0000,
5606 0xffffffff,
5607 {0},
5608 {1},
5609 {nullptr, 1},
5610 0x01,
5611 {nullptr, 0},
5612 {expected_opaque_data.data(), expected_opaque_data.size()}}}};
5613 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5614
5615 foreach_pldm_package_component_image_information(iter, info, rc)
5616 {
5617 const struct pldm_package_component_image_information* expected;
5618 const char* version;
5619 uint8_t image;
5620
5621 expected = &expected_infos.at(nr_infos);
5622 version = component_versions.at(nr_infos);
5623 image = expected_images.at(nr_infos);
5624
5625 EXPECT_EQ(info.component_classification,
5626 expected->component_classification);
5627 EXPECT_EQ(info.component_identifier, expected->component_identifier);
5628 EXPECT_EQ(info.component_comparison_stamp,
5629 expected->component_comparison_stamp);
5630 EXPECT_EQ(info.component_options.value,
5631 expected->component_options.value);
5632 EXPECT_EQ(info.requested_component_activation_method.value,
5633 expected->requested_component_activation_method.value);
5634 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5635 EXPECT_EQ(info.component_image.length,
5636 expected->component_image.length);
5637 EXPECT_EQ(*info.component_image.ptr, image);
5638 EXPECT_EQ(info.component_version_string_type,
5639 expected->component_version_string_type);
5640 ASSERT_EQ(info.component_version_string.length, 4);
5641 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5642 info.component_version_string.length),
5643 0);
5644 EXPECT_EQ(info.component_opaque_data.length,
5645 expected->component_opaque_data.length);
5646 EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
5647 expected->component_opaque_data.ptr,
5648 expected->component_opaque_data.length),
5649 0);
5650 nr_infos++;
5651 }
5652 ASSERT_EQ(rc, 0);
5653
5654 EXPECT_EQ(nr_infos, 2);
5655}
5656#endif