blob: 9566af651da85bcd94c35a4a5044a825f2c69bd1 [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
Andrew Jeffery150b06c2025-03-12 14:17:42 +103058static constexpr size_t PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 = 43;
59
60static constexpr std::array<uint8_t, PLDM_TIMESTAMP104_SIZE>
61 testPackageReleaseDateTime{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
Andrew Jefferye038b962025-03-06 16:04:59 +103063
Andrew Jeffery9c766792022-08-10 23:12:49 +093064TEST(DecodePackageHeaderInfo, goodPath)
65{
Andrew Jeffery9c766792022-08-10 23:12:49 +093066 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +093067 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +103068 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +103069 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +093070
Andrew Jefferya3eba612025-03-06 17:11:20 +103071 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +103072 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
73 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
75 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
76 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x61, 0xe3, 0x64, 0x6e};
Andrew Jeffery9c766792022-08-10 23:12:49 +093077 pldm_package_header_information pkgHeader{};
78 variable_field packageVersion{};
79
80 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
81 packagerHeaderInfo.size(),
82 &pkgHeader, &packageVersion);
83
Andrew Jeffery150b06c2025-03-12 14:17:42 +103084 ASSERT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093085 EXPECT_EQ(true,
86 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
Andrew Jefferye038b962025-03-06 16:04:59 +103087 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.begin(),
88 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.end()));
89 EXPECT_EQ(pkgHeader.package_header_format_version,
90 PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0);
Andrew Jeffery150b06c2025-03-12 14:17:42 +103091 EXPECT_EQ(pkgHeader.package_header_size, packageHeaderSize);
Andrew Jeffery9c766792022-08-10 23:12:49 +093092 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
93 pkgHeader.package_release_date_time +
94 PLDM_TIMESTAMP104_SIZE,
Andrew Jeffery150b06c2025-03-12 14:17:42 +103095 testPackageReleaseDateTime.begin(),
96 testPackageReleaseDateTime.end()));
Andrew Jeffery9c766792022-08-10 23:12:49 +093097 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
98 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
99 EXPECT_EQ(pkgHeader.package_version_string_length,
100 packageVersionStr.size());
101 std::string packageVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930102 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930103 reinterpret_cast<const char*>(packageVersion.ptr),
104 packageVersion.length);
105 EXPECT_EQ(packageVersionString, packageVersionStr);
106}
107
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030108TEST(DecodePackageHeaderInfo, invalidArguments)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930109{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930110 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +1030111 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030112 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930113
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030114 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030115 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
116 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
118 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
119 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030120
121 pldm_package_header_information packageHeader{};
122 variable_field packageVersion{};
123 int rc = 0;
124
125 rc = decode_pldm_package_header_info(nullptr, packagerHeaderInfo.size(),
126 &packageHeader, &packageVersion);
127 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
128
129 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
130 packagerHeaderInfo.size(), nullptr,
131 &packageVersion);
132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
133
134 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
135 packagerHeaderInfo.size(),
136 &packageHeader, nullptr);
137 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
138}
139
140TEST(DecodePackageHeaderInfo, invalidPackageLengths)
141{
142 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
143 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030144 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030145
146 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030147 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
148 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
150 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
151 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030152
153 pldm_package_header_information packageHeader{};
154 variable_field packageVersion{};
155 int rc = 0;
156
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030157 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 0,
158 &packageHeader, &packageVersion);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030159 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030160
161 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 35,
162 &packageHeader, &packageVersion);
163 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
164
165 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 36,
166 &packageHeader, &packageVersion);
167 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
168
169 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
170 packagerHeaderInfo.size() - 1,
171 &packageHeader, &packageVersion);
172 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
173}
174
175TEST(DecodePackageHeaderInfo, unspecifiedPackageHeaderIdentifier)
176{
177 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
178 constexpr size_t packageHeaderSize =
179 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
180
181 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
182 0xff, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
183 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
185 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
186 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
187
188 pldm_package_header_information packageHeader{};
189 variable_field packageVersion{};
190 int rc = 0;
191
192 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
193 packagerHeaderInfo.size(),
194 &packageHeader, &packageVersion);
195 EXPECT_EQ(rc, PLDM_ERROR);
196}
197
198TEST(DecodePackageHeaderInfo, incongruentPackageHeaderFormatRevision)
199{
200 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
201 constexpr size_t packageHeaderSize =
202 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + 1 + packageVersionStr.size();
203
204 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
205 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
206 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x37, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
208 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
209 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
210
211 pldm_package_header_information packageHeader{};
212 variable_field packageVersion{};
213 int rc = 0;
214
215 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
216 packagerHeaderInfo.size(),
217 &packageHeader, &packageVersion);
Andrew Jeffery2613c272025-03-12 14:15:41 +1030218 EXPECT_EQ(rc, PLDM_ERROR);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030219}
220
221TEST(DecodePackageHeaderInfo, invalidPackageVersionStringType)
222{
223 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
224 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030225 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030226
227 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030228 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
229 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
231 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
232 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930233
234 pldm_package_header_information packageHeader{};
235 variable_field packageVersion{};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030236 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930237
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030238 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
239 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930240 &packageHeader, &packageVersion);
241 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030242}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930243
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030244TEST(DecodePackageHeaderInfo, invalidPackageVersionStringLength)
245{
246 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
247 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030248 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930249
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030250 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030251 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
252 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
253 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
254 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
255 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030256
257 pldm_package_header_information packageHeader{};
258 variable_field packageVersion{};
259 int rc = 0;
260
261 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
262 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930263 &packageHeader, &packageVersion);
264 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030265}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930266
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030267TEST(DecodePackageHeaderInfo, corruptPackageVersionStringLength)
268{
269 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
270 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030271 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030272
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030273 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
274 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
275 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
277 0x00, 0x01, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
278 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030279
280 pldm_package_header_information packageHeader{};
281 variable_field packageVersion{};
282 int rc = 0;
283
284 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
285 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930286 &packageHeader, &packageVersion);
287 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030288}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930289
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030290TEST(DecodePackageHeaderInfo, invalidComponentBitmapBitLength)
291{
292 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
293 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030294 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030295
296 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030297 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
298 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x07,
300 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
301 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
302
303 pldm_package_header_information packageHeader{};
304 variable_field packageVersion{};
305 int rc = 0;
306
307 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
308 invalidPackagerHeaderInfo.size(),
309 &packageHeader, &packageVersion);
310 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
311}
312
313TEST(DecodePackageHeaderInfo, badChecksum)
314{
315 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
316 constexpr size_t packageHeaderSize =
317 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
318
319 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
320 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
321 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x10,
323 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
324 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030325
326 pldm_package_header_information packageHeader{};
327 variable_field packageVersion{};
328 int rc = 0;
329
330 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
331 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930332 &packageHeader, &packageVersion);
333 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
334}
335
336TEST(DecodeFirmwareDeviceIdRecord, goodPath)
337{
338 constexpr uint8_t descriptorCount = 1;
339 // Continue component updates after failure
340 constexpr std::bitset<32> deviceUpdateFlag{1};
341 constexpr uint16_t componentBitmapBitLength = 16;
342 // Applicable Components - 1,2,5,8,9
343 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
344 // ComponentImageSetVersionString
345 constexpr std::string_view imageSetVersionStr{"VersionString1"};
346 // Initial descriptor - UUID
347 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
348 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
349 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
350 constexpr uint16_t fwDevicePkgDataLen = 2;
351 // FirmwareDevicePackageData
352 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
353 0xcd};
354 // Size of the firmware device ID record
355 constexpr uint16_t recordLen =
356 sizeof(pldm_firmware_device_id_record) +
357 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
358 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
359 uuid.size() + fwDevicePkgData.size();
360 // Firmware device ID record
361 constexpr std::array<uint8_t, recordLen> record{
362 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
363 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
364 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
365 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
366 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
367
368 pldm_firmware_device_id_record deviceIdRecHeader{};
369 variable_field applicableComponents{};
370 variable_field outCompImageSetVersionStr{};
371 variable_field recordDescriptors{};
372 variable_field outFwDevicePkgData{};
373
374 auto rc = decode_firmware_device_id_record(
375 record.data(), record.size(), componentBitmapBitLength,
376 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
377 &recordDescriptors, &outFwDevicePkgData);
378
Andrew Jefferybacbbac2025-03-12 04:02:18 +0000379 ASSERT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930380 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
381 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
382 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
383 deviceUpdateFlag);
384 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
385 PLDM_STR_TYPE_ASCII);
386 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
387 imageSetVersionStr.size());
388 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
389
390 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
391 EXPECT_EQ(true,
392 std::equal(applicableComponents.ptr,
393 applicableComponents.ptr + applicableComponents.length,
394 applicableComponentsBitfield.begin(),
395 applicableComponentsBitfield.end()));
396
397 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
398 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930399 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930400 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
401 outCompImageSetVersionStr.length);
402 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
403
404 uint16_t descriptorType = 0;
405 uint16_t descriptorLen = 0;
406 variable_field descriptorData{};
407 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
408 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
409 recordDescriptors.length,
410 &descriptorType, &descriptorData);
411 EXPECT_EQ(rc, PLDM_SUCCESS);
412 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
413 sizeof(descriptorLen) +
414 descriptorData.length);
415 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
416 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
417 EXPECT_EQ(true, std::equal(descriptorData.ptr,
418 descriptorData.ptr + descriptorData.length,
419 uuid.begin(), uuid.end()));
420
421 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
422 EXPECT_EQ(true,
423 std::equal(outFwDevicePkgData.ptr,
424 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
425 fwDevicePkgData.begin(), fwDevicePkgData.end()));
426}
427
428TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
429{
430 constexpr uint8_t descriptorCount = 1;
431 // Continue component updates after failure
432 constexpr std::bitset<32> deviceUpdateFlag{1};
433 constexpr uint16_t componentBitmapBitLength = 8;
434 // Applicable Components - 1,2
435 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
436 // ComponentImageSetVersionString
437 constexpr std::string_view imageSetVersionStr{"VersionString1"};
438 // Initial descriptor - UUID
439 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
440 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
441 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
442 constexpr uint16_t fwDevicePkgDataLen = 0;
443
444 // Size of the firmware device ID record
445 constexpr uint16_t recordLen =
446 sizeof(pldm_firmware_device_id_record) +
447 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
448 imageSetVersionStr.size() +
449 sizeof(pldm_descriptor_tlv().descriptor_type) +
450 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
451 fwDevicePkgDataLen;
452 // Firmware device ID record
453 constexpr std::array<uint8_t, recordLen> record{
454 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
455 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
456 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
457 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
458
459 pldm_firmware_device_id_record deviceIdRecHeader{};
460 variable_field applicableComponents{};
461 variable_field outCompImageSetVersionStr{};
462 variable_field recordDescriptors{};
463 variable_field outFwDevicePkgData{};
464
465 auto rc = decode_firmware_device_id_record(
466 record.data(), record.size(), componentBitmapBitLength,
467 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
468 &recordDescriptors, &outFwDevicePkgData);
469
470 EXPECT_EQ(rc, PLDM_SUCCESS);
471 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
472 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
473 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
474 deviceUpdateFlag);
475 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
476 PLDM_STR_TYPE_ASCII);
477 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
478 imageSetVersionStr.size());
479 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
480
481 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
482 EXPECT_EQ(true,
483 std::equal(applicableComponents.ptr,
484 applicableComponents.ptr + applicableComponents.length,
485 applicableComponentsBitfield.begin(),
486 applicableComponentsBitfield.end()));
487
488 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
489 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930490 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930491 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
492 outCompImageSetVersionStr.length);
493 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
494
495 uint16_t descriptorType = 0;
496 uint16_t descriptorLen = 0;
497 variable_field descriptorData{};
498 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
499 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
500 recordDescriptors.length,
501 &descriptorType, &descriptorData);
502 EXPECT_EQ(rc, PLDM_SUCCESS);
503 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
504 sizeof(descriptorLen) +
505 descriptorData.length);
506 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
507 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
508 EXPECT_EQ(true, std::equal(descriptorData.ptr,
509 descriptorData.ptr + descriptorData.length,
510 uuid.begin(), uuid.end()));
511
512 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
513 EXPECT_EQ(outFwDevicePkgData.length, 0);
514}
515
516TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
517{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930518 // Invalid ComponentImageSetVersionStringType
Andrew Jeffery92c32362025-03-10 03:36:46 +0000519 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
520 0x00, 0x06, 0x0e, 0x00, 0x00};
521 constexpr uint16_t componentBitmapBitLength = 8;
522
523 pldm_firmware_device_id_record deviceIdRecHeader{};
524 variable_field outCompImageSetVersionStr{};
525 variable_field applicableComponents{};
526 variable_field outFwDevicePkgData{};
527 variable_field recordDescriptors{};
528 int rc = 0;
529
530 rc = decode_firmware_device_id_record(
531 nullptr, rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
532 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
533 &outFwDevicePkgData);
534 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
535
536 rc = decode_firmware_device_id_record(
537 rec.data(), rec.size(), componentBitmapBitLength, nullptr,
538 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
539 &outFwDevicePkgData);
540 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
541
542 rc = decode_firmware_device_id_record(
543 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
544 nullptr, &outCompImageSetVersionStr, &recordDescriptors,
545 &outFwDevicePkgData);
546 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
547
548 rc = decode_firmware_device_id_record(
549 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
550 &applicableComponents, nullptr, &recordDescriptors,
551 &outFwDevicePkgData);
552 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
553
554 rc = decode_firmware_device_id_record(
555 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
556 &applicableComponents, &outCompImageSetVersionStr, nullptr,
557 &outFwDevicePkgData);
558 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
559
560 rc = decode_firmware_device_id_record(
561 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
562 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
563 nullptr);
564 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
565
566 rc = decode_firmware_device_id_record(
567 rec.data(), rec.size() - 1, componentBitmapBitLength,
568 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
569 &recordDescriptors, &outFwDevicePkgData);
570 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
571
572 rc = decode_firmware_device_id_record(
573 rec.data(), rec.size(), componentBitmapBitLength + 1,
574 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
575 &recordDescriptors, &outFwDevicePkgData);
576 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
577
578 rc = decode_firmware_device_id_record(
579 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
580 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
581 &outFwDevicePkgData);
582 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
583}
584
585TEST(DecodeFirmwareDeviceIdRecord, invalidComponentImageSetVersionStringLength)
586{
587 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
588 0x00, 0x01, 0x00, 0x00, 0x00};
589 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930590
591 int rc = 0;
592 pldm_firmware_device_id_record deviceIdRecHeader{};
593 variable_field applicableComponents{};
594 variable_field outCompImageSetVersionStr{};
595 variable_field recordDescriptors{};
596 variable_field outFwDevicePkgData{};
597
598 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000599 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
600 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930601 &outFwDevicePkgData);
602 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000603}
604
605TEST(DecodeFirmwareDeviceIdRecord, shortBuffer)
606{
607 constexpr std::array<uint8_t, 11> rec{0x2e, 0x00, 0x01, 0x01, 0x00, 0x00,
608 0x00, 0x01, 0x0e, 0x00, 0x00};
609 constexpr uint16_t componentBitmapBitLength = 8;
610
611 pldm_firmware_device_id_record deviceIdRecHeader{};
612 variable_field outCompImageSetVersionStr{};
613 variable_field applicableComponents{};
614 variable_field outFwDevicePkgData{};
615 variable_field recordDescriptors{};
616 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930617
618 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000619 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
620 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
621 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930622 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000623}
624
625TEST(DecodeFirmwareDeviceIdRecord, recordLengthMismatch)
626{
627 constexpr std::array<uint8_t, 11> rec{0x15, 0x00, 0x01, 0x01, 0x00, 0x00,
628 0x00, 0x01, 0x0e, 0x02, 0x00};
629 constexpr uint16_t componentBitmapBitLength = 8;
630
631 pldm_firmware_device_id_record deviceIdRecHeader{};
632 variable_field outCompImageSetVersionStr{};
633 variable_field applicableComponents{};
634 variable_field outFwDevicePkgData{};
635 variable_field recordDescriptors{};
636 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930637
638 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000639 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
640 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
641 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930642 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000643}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930644
Andrew Jeffery92c32362025-03-10 03:36:46 +0000645TEST(DecodeFirmwareDeviceIdRecord, invalidFirmwareDevicePackageDataLength)
646{
647 constexpr std::array<uint8_t, 49> rec{
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800648 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
649 // FirmwareDevicePackageDataLength = 0xffff
650 0xff, 0xff,
651 //
652 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
653 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
654 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
655 0xab, 0xcd};
Andrew Jeffery92c32362025-03-10 03:36:46 +0000656 constexpr uint16_t componentBitmapBitLength = 8;
657
658 pldm_firmware_device_id_record deviceIdRecHeader{};
659 variable_field outCompImageSetVersionStr{};
660 variable_field applicableComponents{};
661 variable_field outFwDevicePkgData{};
662 variable_field recordDescriptors{};
663 int rc = 0;
664
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800665 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000666 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
667 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
668 &outFwDevicePkgData);
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800669 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930670}
671
672TEST(DecodeDescriptors, goodPath3Descriptors)
673{
674 // In the descriptor data there are 3 descriptor entries
675 // 1) IANA enterprise ID
676 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
677 0x0a, 0x0b, 0x0c, 0xd};
678 // 2) UUID
679 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
680 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
681 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
682 // 3) Vendor Defined
683 constexpr std::string_view vendorTitle{"OpenBMC"};
684 constexpr size_t vendorDescriptorLen = 2;
685 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
686 0x01, 0x02};
687
688 constexpr size_t vendorDefinedDescriptorLen =
689 sizeof(pldm_vendor_defined_descriptor_title_data()
690 .vendor_defined_descriptor_title_str_type) +
691 sizeof(pldm_vendor_defined_descriptor_title_data()
692 .vendor_defined_descriptor_title_str_len) +
693 vendorTitle.size() + vendorDescriptorData.size();
694
695 constexpr size_t descriptorsLength =
696 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
697 sizeof(pldm_descriptor_tlv().descriptor_length)) +
698 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
699
700 constexpr std::array<uint8_t, descriptorsLength> descriptors{
701 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
702 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600703 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930704 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
705
706 size_t descriptorCount = 1;
707 size_t descriptorsRemainingLength = descriptorsLength;
708 int rc = 0;
709
710 while (descriptorsRemainingLength && (descriptorCount <= 3))
711 {
712 uint16_t descriptorType = 0;
713 uint16_t descriptorLen = 0;
714 variable_field descriptorData{};
715
716 rc = decode_descriptor_type_length_value(
717 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
718 descriptorsRemainingLength, &descriptorType, &descriptorData);
719 EXPECT_EQ(rc, PLDM_SUCCESS);
720
721 if (descriptorCount == 1)
722 {
723 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
724 EXPECT_EQ(descriptorData.length,
725 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
726 EXPECT_EQ(true,
727 std::equal(descriptorData.ptr,
728 descriptorData.ptr + descriptorData.length,
729 iana.begin(), iana.end()));
730 }
731 else if (descriptorCount == 2)
732 {
733 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
734 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
735 EXPECT_EQ(true,
736 std::equal(descriptorData.ptr,
737 descriptorData.ptr + descriptorData.length,
738 uuid.begin(), uuid.end()));
739 }
740 else if (descriptorCount == 3)
741 {
742 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
743 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
744
745 uint8_t descriptorTitleStrType = 0;
746 variable_field descriptorTitleStr{};
747 variable_field vendorDefinedDescriptorData{};
748
749 rc = decode_vendor_defined_descriptor_value(
750 descriptorData.ptr, descriptorData.length,
751 &descriptorTitleStrType, &descriptorTitleStr,
752 &vendorDefinedDescriptorData);
753 EXPECT_EQ(rc, PLDM_SUCCESS);
754
755 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
756 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
757 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930758 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930759 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
760 descriptorTitleStr.length);
761 EXPECT_EQ(vendorTitleStr, vendorTitle);
762
763 EXPECT_EQ(vendorDefinedDescriptorData.length,
764 vendorDescriptorData.size());
765 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
766 vendorDefinedDescriptorData.ptr +
767 vendorDefinedDescriptorData.length,
768 vendorDescriptorData.begin(),
769 vendorDescriptorData.end()));
770 }
771
772 descriptorsRemainingLength -= sizeof(descriptorType) +
773 sizeof(descriptorLen) +
774 descriptorData.length;
775 descriptorCount++;
776 }
777}
778
779TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
780{
781 int rc = 0;
782 // IANA Enterprise ID descriptor length incorrect
783 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
784 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
785 uint16_t descriptorType = 0;
786 variable_field descriptorData{};
787
788 rc = decode_descriptor_type_length_value(nullptr,
789 invalidIANADescriptor1.size(),
790 &descriptorType, &descriptorData);
791 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
792
793 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
794 invalidIANADescriptor1.size(),
795 nullptr, &descriptorData);
796 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
797
798 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
799 invalidIANADescriptor1.size(),
800 &descriptorType, nullptr);
801 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
802
803 rc = decode_descriptor_type_length_value(
804 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
805 &descriptorType, &descriptorData);
806 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
807
808 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
809 invalidIANADescriptor1.size(),
810 &descriptorType, &descriptorData);
Andrew Jeffery779e9db2025-02-21 12:14:28 +1030811 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930812
813 // IANA Enterprise ID descriptor data less than length
814 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
815 0x0a, 0x0b, 0x0c};
816 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
817 invalidIANADescriptor2.size(),
818 &descriptorType, &descriptorData);
819 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
820}
821
822TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
823{
824 int rc = 0;
825 // VendorDefinedDescriptorTitleStringType is invalid
826 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
827 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
828 uint8_t descriptorStringType = 0;
829 variable_field descriptorTitleStr{};
830 variable_field vendorDefinedDescriptorData{};
831
832 rc = decode_vendor_defined_descriptor_value(
833 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
834 &descriptorTitleStr, &vendorDefinedDescriptorData);
835 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
836
837 rc = decode_vendor_defined_descriptor_value(
838 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
839 &descriptorStringType, &descriptorTitleStr,
840 &vendorDefinedDescriptorData);
841 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
842
843 rc = decode_vendor_defined_descriptor_value(
844 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
845 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
846 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
847
848 rc = decode_vendor_defined_descriptor_value(
849 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
850 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
851 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
852
853 rc = decode_vendor_defined_descriptor_value(
854 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
855 &descriptorStringType, &descriptorTitleStr, nullptr);
856 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
857
858 rc = decode_vendor_defined_descriptor_value(
859 invalidVendorDescriptor1.data(),
860 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
861 &descriptorStringType, &descriptorTitleStr,
862 &vendorDefinedDescriptorData);
863 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
864
865 rc = decode_vendor_defined_descriptor_value(
866 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
867 &descriptorStringType, &descriptorTitleStr,
868 &vendorDefinedDescriptorData);
869 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
870
871 // VendorDefinedDescriptorTitleStringLength is 0
872 std::array<uint8_t, 9> invalidVendorDescriptor2{
873 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
874 rc = decode_vendor_defined_descriptor_value(
875 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
876 &descriptorStringType, &descriptorTitleStr,
877 &vendorDefinedDescriptorData);
878 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
879
880 // VendorDefinedDescriptorData not present in the data
881 std::array<uint8_t, 9> invalidVendorDescriptor3{
882 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
883 rc = decode_vendor_defined_descriptor_value(
884 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
885 &descriptorStringType, &descriptorTitleStr,
886 &vendorDefinedDescriptorData);
887 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
888}
889
890TEST(DecodeComponentImageInfo, goodPath)
891{
892 // Firmware
893 constexpr uint16_t compClassification = 16;
894 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600895 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930896 // Force update
897 constexpr std::bitset<16> compOptions{1};
898 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
899 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
900 // Random ComponentLocationOffset
901 constexpr uint32_t compLocOffset = 357;
902 // Random ComponentSize
903 constexpr uint32_t compSize = 27;
904 // ComponentVersionString
905 constexpr std::string_view compVersionStr{"VersionString1"};
906 constexpr size_t compImageInfoSize =
907 sizeof(pldm_component_image_information) + compVersionStr.size();
908
909 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
910 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
911 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
912 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
913 pldm_component_image_information outCompImageInfo{};
914 variable_field outCompVersionStr{};
915
916 auto rc =
917 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
918 &outCompImageInfo, &outCompVersionStr);
919
920 EXPECT_EQ(rc, PLDM_SUCCESS);
921 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
922 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
923 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
924 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
925 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
926 reqCompActivationMethod);
927 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
928 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
929 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
930 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
931 compVersionStr.size());
932
933 EXPECT_EQ(outCompVersionStr.length,
934 outCompImageInfo.comp_version_string_length);
935 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930936 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930937 reinterpret_cast<const char*>(outCompVersionStr.ptr),
938 outCompVersionStr.length);
939 EXPECT_EQ(componentVersionString, compVersionStr);
940}
941
942TEST(DecodeComponentImageInfo, errorPaths)
943{
944 int rc = 0;
945 // ComponentVersionString
946 constexpr std::string_view compVersionStr{"VersionString1"};
947 constexpr size_t compImageInfoSize =
948 sizeof(pldm_component_image_information) + compVersionStr.size();
949 // Invalid ComponentVersionStringType - 0x06
950 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
951 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
952 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
953 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
954 pldm_component_image_information outCompImageInfo{};
955 variable_field outCompVersionStr{};
956
957 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
958 &outCompImageInfo, &outCompVersionStr);
959 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
960
961 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
962 invalidCompImageInfo1.size(), nullptr,
963 &outCompVersionStr);
964 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
965
966 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
967 invalidCompImageInfo1.size(),
968 &outCompImageInfo, nullptr);
969 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
970
971 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
972 sizeof(pldm_component_image_information) -
973 1,
974 &outCompImageInfo, &outCompVersionStr);
975 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
976
977 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
978 invalidCompImageInfo1.size(),
979 &outCompImageInfo, &outCompVersionStr);
980 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
981
982 // Invalid ComponentVersionStringLength - 0x00
983 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
984 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
985 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
986 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
987 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
988 invalidCompImageInfo2.size(),
989 &outCompImageInfo, &outCompVersionStr);
990 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
991
992 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600993 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +0930994 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
995 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
996 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
997 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
998
999 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
1000 invalidCompImageInfo3.size() - 1,
1001 &outCompImageInfo, &outCompVersionStr);
1002 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1003
1004 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
1005 invalidCompImageInfo3.size(),
1006 &outCompImageInfo, &outCompVersionStr);
1007 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1008
1009 // Invalid ComponentLocationOffset - 0
1010 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
1011 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1012 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1013 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1014 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
1015 invalidCompImageInfo4.size(),
1016 &outCompImageInfo, &outCompVersionStr);
1017 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1018
1019 // Invalid ComponentSize - 0
1020 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
1021 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1022 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1023 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1024 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
1025 invalidCompImageInfo5.size(),
1026 &outCompImageInfo, &outCompVersionStr);
1027 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1028}
1029
1030TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
1031{
1032 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301033 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301034 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1035
1036 uint8_t instanceId = 0x01;
1037
1038 auto rc = encode_query_device_identifiers_req(
1039 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
1040 EXPECT_EQ(rc, PLDM_SUCCESS);
1041 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1042 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1043 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1044 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
1045}
1046
1047TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
1048{
1049 // descriptorDataLen is not fixed here taking it as 6
1050 constexpr uint8_t descriptorDataLen = 6;
1051 std::array<uint8_t, hdrSize +
1052 sizeof(struct pldm_query_device_identifiers_resp) +
1053 descriptorDataLen>
1054 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301055 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301056 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
1057 responseMsg.data() + hdrSize);
1058
1059 inResp->completion_code = PLDM_SUCCESS;
1060 inResp->device_identifiers_len = htole32(descriptorDataLen);
1061 inResp->descriptor_count = 1;
1062
1063 // filling descriptor data
1064 std::fill_n(responseMsg.data() + hdrSize +
1065 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001066 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301067
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301068 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301069 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1070 uint8_t completionCode = PLDM_SUCCESS;
1071 uint32_t deviceIdentifiersLen = 0;
1072 uint8_t descriptorCount = 0;
1073 uint8_t* outDescriptorData = nullptr;
1074
1075 auto rc = decode_query_device_identifiers_resp(
1076 response, responseMsg.size() - hdrSize, &completionCode,
1077 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
1078
1079 EXPECT_EQ(rc, PLDM_SUCCESS);
1080 EXPECT_EQ(completionCode, PLDM_SUCCESS);
1081 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
1082 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
1083 EXPECT_EQ(true,
1084 std::equal(outDescriptorData,
1085 outDescriptorData + deviceIdentifiersLen,
1086 responseMsg.begin() + hdrSize +
1087 sizeof(struct pldm_query_device_identifiers_resp),
1088 responseMsg.end()));
1089}
1090
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001091#ifdef LIBPLDM_API_TESTING
1092TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
1093{
1094 int rc;
1095 PLDM_MSG_DEFINE_P(enc, 1000);
1096 size_t enc_payload_len = 1000;
1097 pldm_descriptor check_desc[] = {
1098 {
1099 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
1100 .descriptor_length = 4,
1101 .descriptor_data = "a123",
1102 },
1103 {
1104 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
1105 .descriptor_length = 3,
1106 .descriptor_data = "987",
1107 },
1108 };
1109 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
1110 enc, &enc_payload_len);
1111 EXPECT_EQ(rc, 0);
1112 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
1113 ElementsAreArray<uint8_t>({
1114 // completion code
1115 0x00,
1116 // device identifiers length = 15
1117 0x0f,
1118 0x00,
1119 0x00,
1120 0x00,
1121 // descriptor count
1122 0x02,
1123 // desc 0
1124 0x01,
1125 0x00,
1126 0x04,
1127 0x00,
1128 0x61,
1129 0x31,
1130 0x32,
1131 0x33,
1132 // desc 1
1133 0xff,
1134 0xff,
1135 0x03,
1136 0x00,
1137 0x39,
1138 0x38,
1139 0x37,
1140 }));
1141
1142 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
1143}
1144#endif
1145
Andrew Jeffery9c766792022-08-10 23:12:49 +09301146TEST(GetFirmwareParameters, goodPathEncodeRequest)
1147{
1148 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301149 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301150 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1151 uint8_t instanceId = 0x01;
1152
1153 auto rc = encode_get_firmware_parameters_req(
1154 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
1155 EXPECT_EQ(rc, PLDM_SUCCESS);
1156 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1157 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1158 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1159 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
1160}
1161
1162TEST(GetFirmwareParameters, decodeResponse)
1163{
1164 // CapabilitiesDuringUpdate of the firmware device
1165 // Firmware device downgrade restrictions [Bit position 8] &
1166 // Firmware Device Partial Updates [Bit position 3]
1167 constexpr std::bitset<32> fdCapabilities{0x00000104};
1168 constexpr uint16_t compCount = 1;
1169 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1170 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1171
1172 // constexpr uint16_t compClassification = 16;
1173 // constexpr uint16_t compIdentifier = 300;
1174 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001175 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301176 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
1177 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1178 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
1179 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
1180 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
1181 constexpr std::string_view activeCompVersion{"VersionString3"};
1182 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +09301183
1184 constexpr size_t compParamTableSize =
1185 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
1186 pendingCompVersion.size();
1187
1188 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001189 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301190 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1191 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
1192 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
1193 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1194 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1195
1196 constexpr size_t getFwParamsPayloadLen =
1197 sizeof(pldm_get_firmware_parameters_resp) +
1198 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1199 compParamTableSize;
1200
1201 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1202 getFwParamsResponse{
1203 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1204 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1205 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1206 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001207 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301208 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1209 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1210 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1211 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1212 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1213
1214 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301215 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301216 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1217 pldm_get_firmware_parameters_resp outResp{};
1218 variable_field outActiveCompImageSetVersion{};
1219 variable_field outPendingCompImageSetVersion{};
1220 variable_field outCompParameterTable{};
1221
1222 auto rc = decode_get_firmware_parameters_resp(
1223 responseMsg, getFwParamsPayloadLen, &outResp,
1224 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1225 &outCompParameterTable);
1226
1227 EXPECT_EQ(rc, PLDM_SUCCESS);
1228 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1229 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1230 EXPECT_EQ(outResp.comp_count, compCount);
1231 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1232 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1233 activeCompImageSetVersion.size());
1234 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1235 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1236 pendingCompImageSetVersion.size());
1237 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301238 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301239 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1240 outActiveCompImageSetVersion.length);
1241 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1242 std::string pendingCompImageSetVersionStr(
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*>(outPendingCompImageSetVersion.ptr),
1245 outPendingCompImageSetVersion.length);
1246 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1247 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1248 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1249 outCompParameterTable.ptr +
1250 outCompParameterTable.length,
1251 compParamTable.begin(), compParamTable.end()));
1252}
1253
1254TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1255{
1256 // CapabilitiesDuringUpdate of the firmware device
1257 // FD Host Functionality during Firmware Update [Bit position 2] &
1258 // Component Update Failure Retry Capability [Bit position 1]
1259 constexpr std::bitset<32> fdCapabilities{0x06};
1260 constexpr uint16_t compCount = 0;
1261 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1262 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1263
1264 constexpr size_t getFwParamsPayloadLen =
1265 sizeof(pldm_get_firmware_parameters_resp) +
1266 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1267
1268 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1269 getFwParamsResponse{
1270 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1271 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1272 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1273 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1274
1275 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301276 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301277 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1278 pldm_get_firmware_parameters_resp outResp{};
1279 variable_field outActiveCompImageSetVersion{};
1280 variable_field outPendingCompImageSetVersion{};
1281 variable_field outCompParameterTable{};
1282
1283 auto rc = decode_get_firmware_parameters_resp(
1284 responseMsg, getFwParamsPayloadLen, &outResp,
1285 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1286 &outCompParameterTable);
1287
1288 EXPECT_EQ(rc, PLDM_SUCCESS);
1289 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1290 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1291 EXPECT_EQ(outResp.comp_count, compCount);
1292 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1293 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1294 activeCompImageSetVersion.size());
1295 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1296 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1297 pendingCompImageSetVersion.size());
1298 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301299 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301300 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1301 outActiveCompImageSetVersion.length);
1302 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1303 std::string pendingCompImageSetVersionStr(
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*>(outPendingCompImageSetVersion.ptr),
1306 outPendingCompImageSetVersion.length);
1307 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1308 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1309 EXPECT_EQ(outCompParameterTable.length, 0);
1310}
1311
1312TEST(GetFirmwareParameters,
1313 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1314{
1315 // CapabilitiesDuringUpdate of the firmware device
1316 // FD Host Functionality during Firmware Update [Bit position 2] &
1317 // Component Update Failure Retry Capability [Bit position 1]
1318 constexpr std::bitset<32> fdCapabilities{0x06};
1319 constexpr uint16_t compCount = 0;
1320 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1321
1322 constexpr size_t getFwParamsPayloadLen =
1323 sizeof(pldm_get_firmware_parameters_resp) +
1324 activeCompImageSetVersion.size();
1325
1326 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1327 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1328 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1329 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1330 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1331
1332 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301333 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301334 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1335 pldm_get_firmware_parameters_resp outResp{};
1336 variable_field outActiveCompImageSetVersion{};
1337 variable_field outPendingCompImageSetVersion{};
1338 variable_field outCompParameterTable{};
1339
1340 auto rc = decode_get_firmware_parameters_resp(
1341 responseMsg, getFwParamsPayloadLen, &outResp,
1342 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1343 &outCompParameterTable);
1344
1345 EXPECT_EQ(rc, PLDM_SUCCESS);
1346 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1347 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1348 EXPECT_EQ(outResp.comp_count, compCount);
1349 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1350 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1351 activeCompImageSetVersion.size());
1352 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1353 PLDM_STR_TYPE_UNKNOWN);
1354 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1355 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301356 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301357 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1358 outActiveCompImageSetVersion.length);
1359 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1360 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1361 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1362 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1363 EXPECT_EQ(outCompParameterTable.length, 0);
1364}
1365
1366TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1367{
1368 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1369 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1370
1371 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301372 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301373 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1374 pldm_get_firmware_parameters_resp outResp{};
1375 variable_field outActiveCompImageSetVersion{};
1376 variable_field outPendingCompImageSetVersion{};
1377 variable_field outCompParameterTable{};
1378
1379 auto rc = decode_get_firmware_parameters_resp(
1380 responseMsg, getFwParamsResponse.size(), &outResp,
1381 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1382 &outCompParameterTable);
1383
1384 EXPECT_EQ(rc, PLDM_SUCCESS);
1385 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1386}
1387
1388TEST(GetFirmwareParameters, errorPathdecodeResponse)
1389{
1390 int rc = 0;
1391 // Invalid ActiveComponentImageSetVersionStringType
1392 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1394 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1395
1396 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301397 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301398 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1399 pldm_get_firmware_parameters_resp outResp{};
1400 variable_field outActiveCompImageSetVersion{};
1401 variable_field outPendingCompImageSetVersion{};
1402 variable_field outCompParameterTable{};
1403
1404 rc = decode_get_firmware_parameters_resp(
1405 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1406 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1407 &outCompParameterTable);
1408 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1409
1410 rc = decode_get_firmware_parameters_resp(
1411 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1412 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1413 &outCompParameterTable);
1414 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1415
1416 rc = decode_get_firmware_parameters_resp(
1417 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1418 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1419 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1420
1421 rc = decode_get_firmware_parameters_resp(
1422 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1423 &outActiveCompImageSetVersion, nullptr, &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, &outPendingCompImageSetVersion, nullptr);
1429 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1430
1431 rc = decode_get_firmware_parameters_resp(
1432 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1433 &outPendingCompImageSetVersion, &outCompParameterTable);
1434 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1435
1436 rc = decode_get_firmware_parameters_resp(
1437 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1438 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1439 &outCompParameterTable);
1440 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1441
1442 rc = decode_get_firmware_parameters_resp(
1443 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1444 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1445 &outCompParameterTable);
1446 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1447
1448 // Invalid ActiveComponentImageSetVersionStringLength
1449 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1451 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1452 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301453 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301454 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1455 rc = decode_get_firmware_parameters_resp(
1456 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1457 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1458 &outCompParameterTable);
1459 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1460
1461 // Invalid PendingComponentImageSetVersionStringType &
1462 // PendingComponentImageSetVersionStringLength
1463 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1464 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1465 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1466 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301467 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301468 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1469 rc = decode_get_firmware_parameters_resp(
1470 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1471 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1472 &outCompParameterTable);
1473 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1474
1475 // Invalid PendingComponentImageSetVersionStringType &
1476 // PendingComponentImageSetVersionStringLength
1477 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1478 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1479 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1480 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301481 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301482 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1483 rc = decode_get_firmware_parameters_resp(
1484 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1485 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1486 &outCompParameterTable);
1487 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1488
1489 // Total payload length less than expected
1490 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1491 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1492 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1493 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301494 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301495 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1496 rc = decode_get_firmware_parameters_resp(
1497 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1498 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1499 &outCompParameterTable);
1500 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1501}
1502
1503TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1504{
1505 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001506 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301507 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001508 constexpr uint16_t compIdentifier = 0x0c0d;
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001509 constexpr uint16_t compClassificationIndex = 0xf;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301510 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001511 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301512 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001513 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301514 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001515 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301516
1517 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1518 constexpr uint8_t activeCompVerStrLen = 8;
1519 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1520 constexpr uint8_t pendingCompVerStrLen = 8;
1521 constexpr size_t entryLength =
1522 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1523 pendingCompVerStrLen;
1524 std::array<uint8_t, entryLength> entry{};
1525
1526 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301527 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301528 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1529
1530 inEntry->comp_classification = htole16(compClassification);
1531 inEntry->comp_identifier = htole16(compIdentifier);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001532 inEntry->comp_classification_index = compClassificationIndex;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301533 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1534 inEntry->active_comp_ver_str_type = 1;
1535 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1536 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001537 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301538 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1539 inEntry->pending_comp_ver_str_type = 1;
1540 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1541 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001542 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301543 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1544 inEntry->capabilities_during_update.value =
1545 htole32(capabilitiesDuringUpdate);
1546 constexpr auto activeCompVerStrPos =
1547 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001548 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301549 constexpr auto pendingCompVerStrPos =
1550 activeCompVerStrPos + activeCompVerStrLen;
1551 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001552 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301553
1554 struct pldm_component_parameter_entry outEntry;
1555 struct variable_field outActiveCompVerStr;
1556 struct variable_field outPendingCompVerStr;
1557
1558 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1559 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1560 &outPendingCompVerStr);
1561
1562 EXPECT_EQ(rc, PLDM_SUCCESS);
1563
1564 EXPECT_EQ(outEntry.comp_classification, compClassification);
1565 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1566 EXPECT_EQ(inEntry->comp_classification_index,
1567 outEntry.comp_classification_index);
1568 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1569 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1570 outEntry.active_comp_ver_str_type);
1571 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1572 outEntry.active_comp_ver_str_len);
1573 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1574 outEntry.active_comp_release_date,
1575 sizeof(inEntry->active_comp_release_date)));
1576 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1577 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1578 outEntry.pending_comp_ver_str_type);
1579 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1580 outEntry.pending_comp_ver_str_len);
1581 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1582 outEntry.pending_comp_release_date,
1583 sizeof(inEntry->pending_comp_release_date)));
1584 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1585 EXPECT_EQ(outEntry.capabilities_during_update.value,
1586 capabilitiesDuringUpdate);
1587
1588 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1589 entry.data() + activeCompVerStrPos,
1590 outActiveCompVerStr.length));
1591 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1592 entry.data() + pendingCompVerStrPos,
1593 outPendingCompVerStr.length));
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001594
1595#ifdef LIBPLDM_API_TESTING
1596 /* Check the roundtrip matches */
1597 std::vector<uint8_t> enc_data(1000);
1598 size_t enc_payload_len = enc_data.size();
1599 struct pldm_component_parameter_entry_full entryFull = {
1600 .comp_classification = compClassification,
1601 .comp_identifier = compIdentifier,
1602 .comp_classification_index = compClassificationIndex,
1603 .active_ver =
1604 {
1605 .comparison_stamp = 0x12345678,
1606 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1607 .str_len = activeCompVerStrLen,
1608 .str_data = {}},
1609 .date = {},
1610 },
1611 .pending_ver =
1612 {
1613 .comparison_stamp = 0x12345678,
1614 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1615 .str_len = pendingCompVerStrLen,
1616 .str_data = {}},
1617 .date = {},
1618 },
1619 .comp_activation_methods = inEntry->comp_activation_methods,
1620 .capabilities_during_update = inEntry->capabilities_during_update,
1621 };
1622 // Fill strings
1623 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1624 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1625 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1626 0xff);
1627 std::fill_n(entryFull.pending_ver.date,
1628 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1629
1630 rc = encode_get_firmware_parameters_resp_comp_entry(
1631 &entryFull, enc_data.data(), &enc_payload_len);
1632 EXPECT_EQ(rc, PLDM_SUCCESS);
1633 EXPECT_EQ(enc_payload_len, entryLength);
1634 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1635#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301636}
1637
Chris Wang4c1f2c72024-03-21 17:09:44 +08001638TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1639{
1640 constexpr uint8_t instanceId = 1;
1641 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301642 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001643 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1644
1645 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1646
Unive Tien71e935c2024-11-25 17:21:43 +08001647 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001648 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1649 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1650 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1651 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1652}
1653
1654TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1655{
1656 constexpr uint8_t instanceId = 1;
1657
1658 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1659
Unive Tien71e935c2024-11-25 17:21:43 +08001660 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001661}
1662
1663TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1664{
1665 uint8_t completion_code_resp = PLDM_SUCCESS;
1666 uint8_t downstream_device_update_supported_resp =
1667 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1668 uint16_t number_of_downstream_devices_resp = 1;
1669 uint16_t max_number_of_downstream_devices_resp = 1;
1670 /** Capabilities of updating downstream devices
1671 * FDP supports downstream devices dynamically attached [Bit position 0] &
1672 * FDP supports downstream devices dynamically removed [Bit position 1]
1673 */
1674 bitfield32_t capabilities_resp = {.value = 0x0002};
1675 int rc;
1676
1677 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1678 responseMsg{};
1679
Andrew Jefferya1896962025-03-03 21:41:25 +10301680 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301681 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1682 responseMsg.size() - hdrSize);
1683 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001684
1685 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1686 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1687 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1688 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1689 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301690 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001691
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301692 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001693 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1694 struct pldm_query_downstream_devices_resp resp_data;
1695
1696 rc = decode_query_downstream_devices_resp(
1697 response, responseMsg.size() - hdrSize, &resp_data);
1698
Unive Tien71e935c2024-11-25 17:21:43 +08001699 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001700 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1701 EXPECT_EQ(resp_data.downstream_device_update_supported,
1702 downstream_device_update_supported_resp);
1703 EXPECT_EQ(resp_data.number_of_downstream_devices,
1704 number_of_downstream_devices_resp);
1705 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1706 max_number_of_downstream_devices_resp);
1707 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1708}
1709
1710TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1711{
1712 uint8_t completion_code_resp = PLDM_SUCCESS;
1713 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1714 uint16_t number_of_downstream_devices_resp = 1;
1715 uint16_t max_number_of_downstream_devices_resp = 1;
1716 /** Capabilities of updating downstream devices
1717 * FDP supports downstream devices dynamically attached [Bit position 0] &
1718 * FDP supports downstream devices dynamically removed [Bit position 1]
1719 */
1720 bitfield32_t capabilities_resp = {.value = 0x0002};
1721 int rc;
1722
1723 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1724 responseMsg{};
1725
Andrew Jefferya1896962025-03-03 21:41:25 +10301726 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301727 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1728 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301729 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001730 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1731 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1732 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1733 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1734 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301735 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001736
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301737 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001738 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1739 struct pldm_query_downstream_devices_resp resp_data;
1740
1741 rc = decode_query_downstream_devices_resp(
1742 response, responseMsg.size() - hdrSize, &resp_data);
1743
Unive Tien71e935c2024-11-25 17:21:43 +08001744 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001745}
1746
1747TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1748{
1749 uint8_t completion_code_resp = PLDM_SUCCESS;
1750 uint8_t downstream_device_update_supported_resp =
1751 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1752 uint16_t number_of_downstream_devices_resp = 1;
1753 uint16_t max_number_of_downstream_devices_resp = 1;
1754 /** Capabilities of updating downstream devices
1755 * FDP supports downstream devices dynamically attached [Bit position 0] &
1756 * FDP supports downstream devices dynamically removed [Bit position 1]
1757 */
1758 bitfield32_t capabilities_resp = {.value = 0x0002};
1759 int rc;
1760
1761 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1762 2 /* Inject error length*/>
1763 responseMsg{};
1764
Andrew Jefferya1896962025-03-03 21:41:25 +10301765 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301766 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1767 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301768 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001769
1770 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1771 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1772 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1773 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1774 // Inject error value
1775 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301776 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001777
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301778 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001779 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1780 struct pldm_query_downstream_devices_resp resp_data;
1781
1782 rc = decode_query_downstream_devices_resp(
1783 response, responseMsg.size() - hdrSize, &resp_data);
1784
Unive Tien71e935c2024-11-25 17:21:43 +08001785 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001786}
1787
Chris Wang458475a2024-03-26 17:59:19 +08001788TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1789{
1790 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301791 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1792 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001793 constexpr pldm_query_downstream_identifiers_req params_req{
1794 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001795
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001796 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1797 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001798 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301799 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1800 ElementsAreArray<uint8_t>(
1801 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001802}
1803
1804TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1805{
1806 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001807 constexpr pldm_query_downstream_identifiers_req params_req{
1808 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1809 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1810 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001811 constexpr size_t payload_length =
1812 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1813 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301814 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001815 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1816
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001817 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1818 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001819 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001820
1821 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001822 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001823 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001824
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001825 rc = encode_query_downstream_identifiers_req(
1826 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001827 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001828}
1829
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301830TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001831{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301832 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1833 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1834 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1835 constexpr uint32_t downstream_devices_length_resp = 0;
1836 constexpr uint16_t number_of_downstream_devices_resp = 0;
1837
1838 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1839 struct pldm_query_downstream_identifiers_resp resp_data = {};
1840 struct pldm_downstream_device_iter devs;
Andrew Jefferya1896962025-03-03 21:41:25 +10301841 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301842 int rc = 0;
1843
1844 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1845 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1846 ASSERT_EQ(rc, 0);
1847
1848 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1849 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1850 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1851 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1852 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1853
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301854 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301855
1856 rc = decode_query_downstream_identifiers_resp(
1857 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1858 &devs);
1859
Unive Tien71e935c2024-11-25 17:21:43 +08001860 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301861 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1862 EXPECT_EQ(resp_data.next_data_transfer_handle,
1863 next_data_transfer_handle_resp);
1864 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1865 EXPECT_EQ(resp_data.downstream_devices_length,
1866 downstream_devices_length_resp);
1867 EXPECT_EQ(resp_data.number_of_downstream_devices,
1868 number_of_downstream_devices_resp);
1869}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301870
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301871TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1872{
1873 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1874 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1875 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1876 constexpr uint32_t downstream_devices_length_resp = 0;
1877 constexpr uint16_t number_of_downstream_devices_resp = 1;
1878
1879 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1880 struct pldm_query_downstream_identifiers_resp resp = {};
1881 struct pldm_downstream_device_iter devs;
1882 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301883 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301884 int rc = 0;
1885
1886 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1887 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1888 ASSERT_EQ(rc, 0);
1889
1890 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1891 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1892 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1893 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1894 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1895
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301896 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301897
1898 rc = decode_query_downstream_identifiers_resp(
1899 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001900 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301901
1902 foreach_pldm_downstream_device(devs, dev, rc)
1903 {
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10301904 FAIL();
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301905 }
1906 ASSERT_NE(rc, 0);
1907}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301908
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301909TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1910{
1911 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301912 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001913 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1914 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1915 const uint32_t downstream_devices_length_resp =
1916 htole32(downstreamDevicesLen);
1917 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301918 constexpr size_t payloadLen =
1919 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001920
Andrew Jefferydec237b2024-11-08 14:33:45 +10301921 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301922 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301923 struct pldm_downstream_device_iter devs;
1924 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301925 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301926 int rc = 0;
1927
1928 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1929 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001930
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301931 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001932 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1933 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1934 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1935 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1936
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301937 /* Downstream device */
1938 pldm_msgbuf_insert_uint16(buf, 1);
1939 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001940
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301941 /* Device descriptor */
1942 pldm_msgbuf_insert_uint16(buf, 1);
1943 pldm_msgbuf_insert_uint16(buf, 4);
1944 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001945
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301946 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301947
1948 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1949 &resp_data, &devs);
1950
Unive Tien71e935c2024-11-25 17:21:43 +08001951 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301952 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001953 EXPECT_EQ(resp_data.next_data_transfer_handle,
1954 next_data_transfer_handle_resp);
1955 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1956 EXPECT_EQ(resp_data.downstream_devices_length,
1957 downstream_devices_length_resp);
1958 EXPECT_EQ(resp_data.number_of_downstream_devices,
1959 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301960
1961 foreach_pldm_downstream_device(devs, dev, rc)
1962 {
1963 struct pldm_descriptor desc;
1964
1965 EXPECT_EQ(dev.downstream_device_index, 1);
1966 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1967
1968 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1969 {
1970 static const uint32_t dmtf = htole32(412);
1971 EXPECT_EQ(desc.descriptor_type, 1);
1972 EXPECT_EQ(desc.descriptor_length, 4);
1973 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1974 }
1975 ASSERT_EQ(rc, 0);
1976 }
1977 ASSERT_EQ(rc, 0);
1978}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301979
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301980constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1981constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1982const uint32_t iana_pen_openbmc = htole16(49871u);
1983const uint32_t iana_pen_dmtf = htole16(412u);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301984
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301985TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1986{
1987 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1988 {0, 1},
1989 {1, 1},
1990 }};
1991
1992 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1993 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1994 &iana_pen_dmtf},
1995 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1996 &iana_pen_openbmc},
1997 }};
1998
1999 constexpr uint32_t downstream_devices_len = 22;
2000 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2001 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2002 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2003 const uint32_t downstream_devices_length_resp =
2004 htole32(downstream_devices_len);
2005 constexpr uint16_t number_of_downstream_devices_resp = 2;
2006 constexpr size_t payloadLen =
2007 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2008
Patrick Williamsf37edd72024-12-18 11:22:58 -05002009 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302010 PLDM_MSG_DEFINE_P(response, payloadLen);
2011 struct pldm_downstream_device_iter devs;
2012 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302013 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302014 int rc = 0;
2015
2016 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2017 ASSERT_EQ(rc, 0);
2018
2019 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2020 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2021 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2022 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2023 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2024
2025 /* Downstream device */
2026 pldm_msgbuf_insert_uint16(buf, 0);
2027 pldm_msgbuf_insert_uint8(buf, 1);
2028
2029 /* Device descriptor */
2030 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2031 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2032 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2033
2034 /* Downstream device */
2035 pldm_msgbuf_insert_uint16(buf, 1);
2036 pldm_msgbuf_insert_uint8(buf, 1);
2037
2038 /* Device descriptor */
2039 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2040 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2041 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2042
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302043 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302044
2045 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2046 &resp_data, &devs);
2047
Unive Tien71e935c2024-11-25 17:21:43 +08002048 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302049 EXPECT_EQ(resp_data.number_of_downstream_devices,
2050 number_of_downstream_devices_resp);
2051
2052 size_t devIndex = 0;
2053 size_t descIndex = 0;
2054 foreach_pldm_downstream_device(devs, dev, rc)
2055 {
2056 struct pldm_descriptor desc;
2057
2058 ASSERT_LT(devIndex, expected_devices.size());
2059
2060 const struct pldm_downstream_device* expectedDev =
2061 &expected_devices[devIndex];
2062
2063 EXPECT_EQ(dev.downstream_device_index,
2064 expectedDev->downstream_device_index);
2065 EXPECT_EQ(dev.downstream_descriptor_count,
2066 expectedDev->downstream_descriptor_count);
2067
2068 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2069 {
2070 ASSERT_LT(descIndex, expected_descriptors.size());
2071
2072 const struct pldm_descriptor* expectedDesc =
2073 &expected_descriptors[descIndex];
2074
2075 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2076 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2077 EXPECT_EQ(memcmp(desc.descriptor_data,
2078 expectedDesc->descriptor_data,
2079 expectedDesc->descriptor_length),
2080 0);
2081
2082 descIndex++;
2083 }
2084 ASSERT_EQ(rc, 0);
2085 EXPECT_EQ(descIndex, 1 * devIndex + 1);
2086
2087 devIndex++;
2088 }
2089 ASSERT_EQ(rc, 0);
2090 EXPECT_EQ(devIndex, 2);
2091}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302092
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302093TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
2094{
2095 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2096 {0, 2},
2097 {1, 1},
2098 }};
2099
2100 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2101 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2102 &iana_pen_dmtf},
2103 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2104 &iana_pen_openbmc},
2105 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2106 &iana_pen_dmtf},
2107 }};
2108
2109 constexpr uint32_t downstream_devices_len = 30;
2110 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2111 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2112 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2113 const uint32_t downstream_devices_length_resp =
2114 htole32(downstream_devices_len);
2115 constexpr uint16_t number_of_downstream_devices_resp = 2;
2116 constexpr size_t payloadLen =
2117 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2118
Patrick Williamsf37edd72024-12-18 11:22:58 -05002119 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302120 PLDM_MSG_DEFINE_P(response, payloadLen);
2121 struct pldm_downstream_device_iter devs;
2122 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302123 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302124 int rc = 0;
2125
2126 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2127 ASSERT_EQ(rc, 0);
2128
2129 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2130 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2131 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2132 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2133 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2134
2135 /* Downstream device */
2136 pldm_msgbuf_insert_uint16(buf, 0);
2137 pldm_msgbuf_insert_uint8(buf, 2);
2138
2139 /* Device descriptor */
2140 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2141 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2142 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
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_openbmc);
2148
2149 /* Downstream device */
2150 pldm_msgbuf_insert_uint16(buf, 1);
2151 pldm_msgbuf_insert_uint8(buf, 1);
2152
2153 /* Device descriptor */
2154 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2155 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2156 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2157
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302158 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302159
2160 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2161 &resp_data, &devs);
2162
Unive Tien71e935c2024-11-25 17:21:43 +08002163 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302164 EXPECT_EQ(resp_data.number_of_downstream_devices,
2165 number_of_downstream_devices_resp);
2166
2167 size_t devIndex = 0;
2168 size_t descIndex = 0;
2169 foreach_pldm_downstream_device(devs, dev, rc)
2170 {
2171 struct pldm_descriptor desc;
2172
2173 ASSERT_LT(devIndex, expected_devices.size());
2174
2175 const struct pldm_downstream_device* expectedDev =
2176 &expected_devices[devIndex];
2177
2178 EXPECT_EQ(dev.downstream_device_index,
2179 expectedDev->downstream_device_index);
2180 EXPECT_EQ(dev.downstream_descriptor_count,
2181 expectedDev->downstream_descriptor_count);
2182
2183 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2184 {
2185 ASSERT_LT(descIndex, expected_descriptors.size());
2186
2187 const struct pldm_descriptor* expectedDesc =
2188 &expected_descriptors[descIndex];
2189
2190 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2191 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2192 EXPECT_EQ(memcmp(desc.descriptor_data,
2193 expectedDesc->descriptor_data,
2194 expectedDesc->descriptor_length),
2195 0);
2196
2197 descIndex++;
2198 }
2199 ASSERT_EQ(rc, 0);
2200
2201 devIndex++;
2202 }
2203 ASSERT_EQ(rc, 0);
2204 EXPECT_EQ(devIndex, 2);
2205 EXPECT_EQ(descIndex, 3);
2206}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302207
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302208TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2209{
2210 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2211 {0, 1},
2212 {1, 2},
2213 }};
2214
2215 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2216 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2217 &iana_pen_dmtf},
2218 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2219 &iana_pen_openbmc},
2220 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2221 &iana_pen_dmtf},
2222 }};
2223
2224 constexpr uint32_t downstream_devices_len = 30;
2225 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2226 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2227 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2228 const uint32_t downstream_devices_length_resp =
2229 htole32(downstream_devices_len);
2230 constexpr uint16_t number_of_downstream_devices_resp = 2;
2231 constexpr size_t payloadLen =
2232 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2233
Patrick Williamsf37edd72024-12-18 11:22:58 -05002234 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302235 PLDM_MSG_DEFINE_P(response, payloadLen);
2236 struct pldm_downstream_device_iter devs;
2237 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302238 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302239 int rc = 0;
2240
2241 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2242 ASSERT_EQ(rc, 0);
2243
2244 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2245 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2246 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2247 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2248 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2249
2250 /* Downstream device */
2251 pldm_msgbuf_insert_uint16(buf, 0);
2252 pldm_msgbuf_insert_uint8(buf, 1);
2253
2254 /* Device descriptor */
2255 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2256 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2257 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2258
2259 /* Downstream device */
2260 pldm_msgbuf_insert_uint16(buf, 1);
2261 pldm_msgbuf_insert_uint8(buf, 2);
2262
2263 /* Device descriptor */
2264 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2265 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2266 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
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_dmtf);
2272
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302273 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302274
2275 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2276 &resp_data, &devs);
2277
Unive Tien71e935c2024-11-25 17:21:43 +08002278 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302279 EXPECT_EQ(resp_data.number_of_downstream_devices,
2280 number_of_downstream_devices_resp);
2281
2282 size_t devIndex = 0;
2283 size_t descIndex = 0;
2284 foreach_pldm_downstream_device(devs, dev, rc)
2285 {
2286 struct pldm_descriptor desc;
2287
2288 ASSERT_LT(devIndex, expected_devices.size());
2289
2290 const struct pldm_downstream_device* expectedDev =
2291 &expected_devices[devIndex];
2292
2293 EXPECT_EQ(dev.downstream_device_index,
2294 expectedDev->downstream_device_index);
2295 EXPECT_EQ(dev.downstream_descriptor_count,
2296 expectedDev->downstream_descriptor_count);
2297
2298 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2299 {
2300 ASSERT_LT(descIndex, expected_descriptors.size());
2301
2302 const struct pldm_descriptor* expectedDesc =
2303 &expected_descriptors[descIndex];
2304
2305 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2306 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2307 EXPECT_EQ(memcmp(desc.descriptor_data,
2308 expectedDesc->descriptor_data,
2309 expectedDesc->descriptor_length),
2310 0);
2311
2312 descIndex++;
2313 }
2314 ASSERT_EQ(rc, 0);
2315
2316 devIndex++;
2317 }
2318 ASSERT_EQ(rc, 0);
2319 EXPECT_EQ(devIndex, 2);
2320 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002321}
2322
2323TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2324{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302325 constexpr size_t payloadLen = sizeof(uint8_t);
2326
Chris Wang458475a2024-03-26 17:59:19 +08002327 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302328 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302329 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002330
2331 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302332 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2333 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002334 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002335
2336 // Test not PLDM_SUCCESS completion code
2337 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302338 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2339 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002340 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002341 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2342
2343 // Test payload length less than minimum length
2344 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302345 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2346 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002347
Unive Tien71e935c2024-11-25 17:21:43 +08002348 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002349}
2350
2351TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2352{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302353 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002354 // 1 descriptor
2355 constexpr uint32_t actualDownstreamDevicesLen = 9;
2356 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2357 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2358 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302359 constexpr uint16_t number_of_downstream_devices_resp = 1;
2360 constexpr size_t payloadLen =
2361 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2362 actualDownstreamDevicesLen;
2363
Chris Wang458475a2024-03-26 17:59:19 +08002364 const uint32_t downstream_devices_length_resp =
2365 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002366
Andrew Jefferydec237b2024-11-08 14:33:45 +10302367 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302368 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302369 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302370 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302371 void* devicesStart = NULL;
2372 size_t devicesLen;
2373 int rc = 0;
2374
2375 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302376 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002377
2378 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2379 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2380 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2381 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2382 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302383 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002384
Andrew Jefferya1896962025-03-03 21:41:25 +10302385 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2386
Chris Wang458475a2024-03-26 17:59:19 +08002387 /** Filling descriptor data, the correctness of the downstream devices data
2388 * is not checked in this test case so filling with 0xff
2389 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302390 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2391 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002392
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302393 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2394 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002395 0);
Chris Wang458475a2024-03-26 17:59:19 +08002396}
2397
2398TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2399{
2400 constexpr uint32_t actualDownstreamDevicesLen = 0;
2401 constexpr uint16_t number_of_downstream_devices_resp = 1;
2402 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2403 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2404 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302405 constexpr size_t payloadLen =
2406 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2407
Chris Wang458475a2024-03-26 17:59:19 +08002408 const uint32_t downstream_devices_length_resp =
2409 htole32(actualDownstreamDevicesLen);
2410
Andrew Jefferydec237b2024-11-08 14:33:45 +10302411 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302412 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302413 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302414 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302415 int rc = 0;
2416
2417 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2418 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002419
2420 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2421 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2422 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2423 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2424 // Inject error buffer size
2425 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
Andrew Jefferya1896962025-03-03 21:41:25 +10302426 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang458475a2024-03-26 17:59:19 +08002427
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302428 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2429 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002430
Unive Tien71e935c2024-11-25 17:21:43 +08002431 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002432}
2433
Chris Wangb6ef35b2024-07-03 09:35:42 +08002434TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2435{
2436 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302437 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002438 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002439 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302440 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002441 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302442 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002443 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2444
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302445 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002446 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002447 EXPECT_EQ(rc, 0);
2448
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302449 std::array<uint8_t,
2450 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002451 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2452 EXPECT_EQ(requestMsg, expectedReq);
2453}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002454
Chris Wangb6ef35b2024-07-03 09:35:42 +08002455TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2456{
2457 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002458 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302459 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002460 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002461 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302462 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002463 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302464 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002465 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2466
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302467 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002468 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002469 EXPECT_EQ(rc, -EBADMSG);
2470}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002471
Chris Wangb6ef35b2024-07-03 09:35:42 +08002472TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2473{
2474 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002475 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302476 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Andrew Jeffery53b08672025-03-04 12:26:18 +10302477 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002478 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302479 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
Chris Wangb6ef35b2024-07-03 09:35:42 +08002480 1 /* inject erro length*/;
2481
2482 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302483 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002484 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2485
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302486 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002487 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002488 EXPECT_EQ(rc, -EOVERFLOW);
2489}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002490
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302491TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002492{
Chris Wangb6ef35b2024-07-03 09:35:42 +08002493 constexpr uint16_t downstreamDeviceCount = 1;
2494 constexpr uint8_t activeComponentVersionStringLength = 8;
2495 constexpr uint8_t pendingComponentVersionStringLength = 8;
2496 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302497 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002498 activeComponentVersionStringLength +
2499 pendingComponentVersionStringLength;
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302500 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002501 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2502 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2503 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302504 constexpr size_t payload_len =
2505 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2506 downstreamDeviceParamTableLen;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002507
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302508 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302509 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302510 int rc = 0;
2511
2512 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302513 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002514
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302515 // Table 24
2516 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002517 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2518 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302519
2520 // Table 25
Chris Wangb6ef35b2024-07-03 09:35:42 +08002521 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2522 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2523
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302524 // Table 26
2525 pldm_msgbuf_insert_uint16(buf, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002526
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302527 // - Active metadata
2528 pldm_msgbuf_insert_uint32(buf, 0);
2529 pldm_msgbuf_insert_uint8(buf, 1);
2530 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2531 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2532 ASSERT_EQ(rc, 0);
2533
2534 // - Pending metadata
2535 pldm_msgbuf_insert_uint32(buf, 0);
2536 pldm_msgbuf_insert_uint8(buf, 1);
2537 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2538 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2539 ASSERT_EQ(rc, 0);
2540
2541 // - Methods and capabilities
2542 pldm_msgbuf_insert_uint16(buf, 1);
2543 pldm_msgbuf_insert_uint32(buf, 0);
2544
2545 // - Version strings
2546 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2547 "abcdefgh", 8);
2548 ASSERT_EQ(rc, 0);
2549 rc = pldm__msgbuf_insert_array_void(
2550 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2551 ASSERT_EQ(rc, 0);
2552
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302553 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302554 ASSERT_EQ(rc, 0);
2555
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302556 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302557 struct pldm_downstream_device_parameters_iter iter = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002558
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302559 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2560 &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002561
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302562 ASSERT_EQ(rc, 0);
2563 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002564 EXPECT_EQ(resp_data.next_data_transfer_handle,
2565 next_data_transfer_handle_resp);
2566 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2567 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302568
2569 struct pldm_downstream_device_parameters_entry entry;
2570 size_t entries = 0;
2571 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2572 {
2573 EXPECT_EQ(entry.downstream_device_index, 0);
2574 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2575 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2576 EXPECT_EQ(entry.active_comp_ver_str_len,
2577 activeComponentVersionStringLength);
2578 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2579 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2580 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2581 EXPECT_EQ(entry.pending_comp_ver_str_len,
2582 pendingComponentVersionStringLength);
2583 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2584 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2585 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2586 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2587 entry.active_comp_ver_str_len));
2588 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2589 entry.pending_comp_ver_str_len));
2590 entries++;
2591 }
2592 EXPECT_EQ(rc, 0);
2593 EXPECT_EQ(entries, 1);
2594}
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302595
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302596TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2597{
2598 /** Count is not fixed here taking it as 1, and the downstream device's
2599 * version strings length are set to 8
2600 */
2601 constexpr uint16_t downstreamDeviceCount = 2;
2602 constexpr uint8_t activeComponentVersionStringLength = 8;
2603 constexpr uint8_t pendingComponentVersionStringLength = 9;
2604 constexpr size_t downstreamDeviceParamTableLen =
2605 static_cast<size_t>(downstreamDeviceCount *
2606 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2607 activeComponentVersionStringLength +
2608 pendingComponentVersionStringLength));
2609 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2610 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2611 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2612 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2613 constexpr size_t payload_len =
2614 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2615 downstreamDeviceParamTableLen;
2616
2617 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302618 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302619 int rc = 0;
2620
2621 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302622 ASSERT_EQ(rc, 0);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302623
2624 // Table 24
2625 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2626 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2627 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2628
2629 // Table 25
2630 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2631 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2632
2633 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2634 table = {{{
2635 0,
2636 0,
2637 1,
2638 8,
2639 "20241206",
2640 0,
2641 1,
2642 9,
2643 "20241209",
2644 {1},
2645 {0},
2646 "active_0",
2647 "pending_0",
2648 },
2649 {
2650 1,
2651 0,
2652 1,
2653 8,
2654 "20241209",
2655 0,
2656 1,
2657 9,
2658 "20241206",
2659 {1},
2660 {0},
2661 "active_1",
2662 "pending_1",
2663 }}};
2664 for (const auto& e : table)
2665 {
2666 // Table 26
2667 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2668
2669 // - Active metadata
2670 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2671 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2672 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2673 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2674 sizeof(e.active_comp_release_date));
2675 ASSERT_EQ(rc, 0);
2676
2677 // - Pending metadata
2678 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2679 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2680 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2681 rc =
2682 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2683 sizeof(e.pending_comp_release_date));
2684 ASSERT_EQ(rc, 0);
2685
2686 // - Methods and capabilities
2687 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2688 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2689
2690 // - Version strings
2691 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2692 e.active_comp_ver_str,
2693 e.active_comp_ver_str_len);
2694 ASSERT_EQ(rc, 0);
2695 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2696 e.pending_comp_ver_str,
2697 e.pending_comp_ver_str_len);
2698 ASSERT_EQ(rc, 0);
2699 }
2700
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302701 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302702 ASSERT_EQ(rc, 0);
2703
2704 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2705 struct pldm_downstream_device_parameters_iter iter = {};
2706
2707 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2708 &resp_data, &iter);
2709
2710 ASSERT_EQ(rc, 0);
2711 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2712 EXPECT_EQ(resp_data.next_data_transfer_handle,
2713 next_data_transfer_handle_resp);
2714 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2715 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2716
2717 struct pldm_downstream_device_parameters_entry entry;
2718 size_t entryIndex = 0;
2719 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2720 {
2721 ASSERT_LE(entryIndex, table.size());
2722
2723 EXPECT_EQ(table[entryIndex].downstream_device_index,
2724 entry.downstream_device_index);
2725 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2726 entry.active_comp_comparison_stamp);
2727 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2728 entry.active_comp_ver_str_type);
2729 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2730 entry.active_comp_ver_str_len);
2731 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2732 &entry.active_comp_release_date[0]);
2733 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2734 entry.pending_comp_comparison_stamp);
2735 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2736 entry.pending_comp_ver_str_type);
2737 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2738 entry.pending_comp_ver_str_len);
2739 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2740 &entry.pending_comp_release_date[0]);
2741 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2742 entry.comp_activation_methods.value);
2743 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2744 entry.capabilities_during_update.value);
2745 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2746 entry.active_comp_ver_str,
2747 table[entryIndex].active_comp_ver_str_len));
2748 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2749 entry.pending_comp_ver_str,
2750 table[entryIndex].pending_comp_ver_str_len));
2751 entryIndex++;
2752 }
2753 EXPECT_EQ(rc, 0);
2754 EXPECT_EQ(entryIndex, table.size());
Chris Wangb6ef35b2024-07-03 09:35:42 +08002755}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002756
Chris Wangb6ef35b2024-07-03 09:35:42 +08002757TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2758{
2759 /** Count is not fixed here taking it as 1, and the downstream device's
2760 * version strings length are set to 8
2761 */
2762 constexpr uint16_t downstreamDeviceCount = 1;
2763 constexpr uint8_t activeComponentVersionStringLength = 8;
2764 constexpr uint8_t pendingComponentVersionStringLength = 8;
2765 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302766 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002767 activeComponentVersionStringLength +
2768 pendingComponentVersionStringLength;
2769 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2770 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2771 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2772 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2773
2774 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302775 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002776 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2777 responseMsg{};
2778
2779 int rc = 0;
2780
Andrew Jefferya1896962025-03-03 21:41:25 +10302781 PLDM_MSGBUF_DEFINE_P(buf);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002782 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2783 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10302784 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002785
2786 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2787 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2788 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2789 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2790 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
Andrew Jefferya1896962025-03-03 21:41:25 +10302791 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002792
2793 /** Filling paramter table, the correctness of the downstream devices data
2794 * is not checked in this test case so filling with 0xff
2795 */
2796 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302797 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002798 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2799 0xff);
2800
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302801 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002802 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302803 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302804 struct pldm_downstream_device_parameters_iter iter;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002805
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302806 rc = decode_get_downstream_firmware_parameters_resp(
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302807 response, responseMsg.size() - hdrSize, &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002808 EXPECT_EQ(rc, 0);
2809
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302810 struct pldm_downstream_device_parameters_entry entry;
2811 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2812 {
2813 FAIL();
2814 }
2815 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002816}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002817
Andrew Jeffery9c766792022-08-10 23:12:49 +09302818TEST(RequestUpdate, goodPathEncodeRequest)
2819{
2820 constexpr uint8_t instanceId = 1;
2821 constexpr uint32_t maxTransferSize = 512;
2822 constexpr uint16_t numOfComp = 3;
2823 constexpr uint8_t maxOutstandingTransferReq = 2;
2824 constexpr uint16_t pkgDataLen = 0x1234;
2825 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2826 constexpr uint8_t compImgSetVerStrLen =
2827 static_cast<uint8_t>(compImgSetVerStr.size());
2828 variable_field compImgSetVerStrInfo{};
2829 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302830 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302831 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2832 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2833
2834 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2835 compImgSetVerStrLen>
2836 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302837 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302838 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2839
2840 auto rc = encode_request_update_req(
2841 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2842 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2843 &compImgSetVerStrInfo, requestMsg,
2844 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2845 EXPECT_EQ(rc, PLDM_SUCCESS);
2846
2847 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2848 compImgSetVerStrLen>
2849 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2850 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2851 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2852 EXPECT_EQ(request, outRequest);
2853}
2854
2855TEST(RequestUpdate, errorPathEncodeRequest)
2856{
2857 constexpr uint8_t instanceId = 1;
2858 uint32_t maxTransferSize = 512;
2859 constexpr uint16_t numOfComp = 3;
2860 uint8_t maxOutstandingTransferReq = 2;
2861 constexpr uint16_t pkgDataLen = 0x1234;
2862 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2863 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2864 variable_field compImgSetVerStrInfo{};
2865 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302866 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302867 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2868 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2869
2870 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2871 compImgSetVerStr.size()>
2872 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302873 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302874 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2875
2876 auto rc = encode_request_update_req(
2877 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2878 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2879 requestMsg,
2880 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2881 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2882
2883 compImgSetVerStrInfo.ptr = nullptr;
2884 rc = encode_request_update_req(
2885 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2886 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2887 &compImgSetVerStrInfo, requestMsg,
2888 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2889 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2890 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302891 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302892 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2893
2894 rc = encode_request_update_req(
2895 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2896 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2897 &compImgSetVerStrInfo, nullptr,
2898 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2899 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2900
2901 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2902 maxOutstandingTransferReq, pkgDataLen,
2903 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2904 &compImgSetVerStrInfo, requestMsg, 0);
2905 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2906
2907 compImgSetVerStrLen = 0;
2908 rc = encode_request_update_req(
2909 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2910 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2911 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2912 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2913 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2914
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002915 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302916 rc = encode_request_update_req(
2917 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2918 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2919 &compImgSetVerStrInfo, nullptr,
2920 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2921 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2922 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2923
2924 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2925 rc = encode_request_update_req(
2926 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2927 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2928 &compImgSetVerStrInfo, nullptr,
2929 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2930 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2931 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2932
Andrew Jefferya1cd72b2025-05-09 12:26:06 +09302933 maxOutstandingTransferReq = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302934 rc = encode_request_update_req(
2935 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2936 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2937 &compImgSetVerStrInfo, nullptr,
2938 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2939 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2940 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2941
2942 rc = encode_request_update_req(
2943 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2944 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2945 &compImgSetVerStrInfo, nullptr,
2946 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2947 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2948}
2949
2950TEST(RequestUpdate, goodPathDecodeResponse)
2951{
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002952 /* Test a success completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302953 constexpr uint16_t fdMetaDataLen = 1024;
2954 constexpr uint8_t fdWillSendPkgData = 1;
2955 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2956 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2957
2958 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302959 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302960 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2961 uint8_t outCompletionCode = 0;
2962 uint16_t outFdMetaDataLen = 0;
2963 uint8_t outFdWillSendPkgData = 0;
2964
2965 auto rc = decode_request_update_resp(
2966 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2967 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2968 EXPECT_EQ(rc, PLDM_SUCCESS);
2969 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2970 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2971 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2972
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002973#ifdef LIBPLDM_API_TESTING
2974 /* Check the success roundtrip matches */
2975 PLDM_MSG_DEFINE_P(enc, 1000);
2976 size_t enc_payload_len = 1000;
2977 const struct pldm_request_update_resp resp_data = {
2978 .completion_code = PLDM_SUCCESS,
2979 .fd_meta_data_len = outFdMetaDataLen,
2980 .fd_will_send_pkg_data = outFdWillSendPkgData,
2981 };
2982 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2983 &enc_payload_len);
2984 EXPECT_EQ(rc, PLDM_SUCCESS);
2985 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2986 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2987 requestUpdateResponse1.end(), enc_buf + hdrSize));
2988 check_response(enc, PLDM_REQUEST_UPDATE);
2989#endif
2990
2991 /* Test a failure completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302992 outCompletionCode = 0;
2993 outFdMetaDataLen = 0;
2994 outFdWillSendPkgData = 0;
2995
2996 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2997 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2998 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302999 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303000 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
3001 rc = decode_request_update_resp(
3002 responseMsg2, requestUpdateResponse2.size() - hdrSize,
3003 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
3004 EXPECT_EQ(rc, PLDM_SUCCESS);
3005 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3006}
3007
3008TEST(RequestUpdate, errorPathDecodeResponse)
3009{
3010 constexpr std::array<uint8_t,
3011 hdrSize + sizeof(pldm_request_update_resp) - 1>
3012 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
3013
3014 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303015 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303016 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
3017 uint8_t outCompletionCode = 0;
3018 uint16_t outFdMetaDataLen = 0;
3019 uint8_t outFdWillSendPkgData = 0;
3020
3021 auto rc = decode_request_update_resp(
3022 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3023 &outFdMetaDataLen, &outFdWillSendPkgData);
3024 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3025
3026 rc = decode_request_update_resp(
3027 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
3028 &outFdMetaDataLen, &outFdWillSendPkgData);
3029 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3030
3031 rc = decode_request_update_resp(
3032 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3033 nullptr, &outFdWillSendPkgData);
3034 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3035
3036 rc = decode_request_update_resp(
3037 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3038 &outFdMetaDataLen, nullptr);
3039 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3040
3041 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
3042 &outFdMetaDataLen, &outFdWillSendPkgData);
3043 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3044
3045 rc = decode_request_update_resp(
3046 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3047 &outFdMetaDataLen, &outFdWillSendPkgData);
3048 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3049}
3050
Sora Su06eadd02025-05-27 11:28:51 +08003051#ifdef LIBPLDM_API_TESTING
3052TEST(RequestDownstreamDeviceUpdate, goodPathEncodeRequest)
3053{
3054 constexpr uint8_t instanceId = 1;
3055
3056 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3057 request{};
3058
3059 auto requestMsg = new (request.data()) pldm_msg;
3060
3061 constexpr struct pldm_request_downstream_device_update_req req_data = {
3062 .maximum_downstream_device_transfer_size = 512,
3063 .maximum_outstanding_transfer_requests = 2,
3064 .downstream_device_package_data_length = 0x1234,
3065 };
3066 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3067
3068 auto rc = encode_request_downstream_device_update_req(
3069 instanceId, &req_data, requestMsg, &enc_payload_len);
3070
3071 EXPECT_EQ(rc, 0);
3072
3073 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3074 outRequest{0x81, 0x05, 0x20, 0x00, 0x02, 0x00, 0x00, 0x02, 0x34, 0x12};
3075 EXPECT_EQ(request, outRequest);
3076}
3077#endif // LIBPLDM_API_TESTING
3078
3079#ifdef LIBPLDM_API_TESTING
3080TEST(RequestDownstreamDeviceUpdate, errorPathEncodeRequest)
3081{
3082 constexpr uint8_t instanceId = 1;
3083 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3084
3085 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3086 request{};
3087
3088 struct pldm_request_downstream_device_update_req req_data = {
3089 .maximum_downstream_device_transfer_size = 512,
3090 .maximum_outstanding_transfer_requests = 2,
3091 .downstream_device_package_data_length = 0x1234,
3092 };
3093
3094 auto requestMsg = new (request.data()) pldm_msg;
3095
3096 auto rc = encode_request_downstream_device_update_req(
3097 instanceId, nullptr, requestMsg, &enc_payload_len);
3098 EXPECT_EQ(rc, -EINVAL);
3099 rc = encode_request_downstream_device_update_req(
3100 instanceId, &req_data, requestMsg, &enc_payload_len);
3101 EXPECT_EQ(rc, 0);
3102
3103 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3104 nullptr, &enc_payload_len);
3105 EXPECT_EQ(rc, -EINVAL);
3106 rc = encode_request_downstream_device_update_req(
3107 instanceId, &req_data, requestMsg, &enc_payload_len);
3108 EXPECT_EQ(rc, 0);
3109
3110 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3111 requestMsg, nullptr);
3112 EXPECT_EQ(rc, -EINVAL);
3113 rc = encode_request_downstream_device_update_req(
3114 instanceId, &req_data, requestMsg, &enc_payload_len);
3115 EXPECT_EQ(rc, 0);
3116
3117 enc_payload_len =
3118 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES) - 1;
3119 rc = encode_request_downstream_device_update_req(
3120 instanceId, &req_data, requestMsg, &enc_payload_len);
3121 EXPECT_EQ(rc, -EOVERFLOW);
3122 enc_payload_len =
3123 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES);
3124 rc = encode_request_downstream_device_update_req(
3125 instanceId, &req_data, requestMsg, &enc_payload_len);
3126 EXPECT_EQ(rc, 0);
3127
3128 req_data.maximum_downstream_device_transfer_size = 31;
3129 rc = encode_request_downstream_device_update_req(
3130 instanceId, &req_data, requestMsg, &enc_payload_len);
3131 EXPECT_EQ(rc, -EINVAL);
3132 req_data.maximum_downstream_device_transfer_size =
3133 PLDM_FWUP_BASELINE_TRANSFER_SIZE;
3134
3135 req_data.maximum_outstanding_transfer_requests = 0;
3136 rc = encode_request_downstream_device_update_req(
3137 instanceId, &req_data, requestMsg, &enc_payload_len);
3138 EXPECT_EQ(rc, -EINVAL);
3139 req_data.maximum_outstanding_transfer_requests = 2;
3140 rc = encode_request_downstream_device_update_req(
3141 instanceId, &req_data, requestMsg, &enc_payload_len);
3142 EXPECT_EQ(rc, 0);
3143}
3144#endif // LIBPLDM_API_TESTING
3145
3146#ifdef LIBPLDM_API_TESTING
3147TEST(RequestDownstreamDeviceUpdate, goodPathDecodeResponse)
3148{
3149 /* Test a success completion code */
3150 constexpr uint16_t ddMetaDataLen = 1024;
3151 constexpr uint8_t ddWillSendPkgData = 1;
3152 constexpr uint16_t getPkgDataMaxTransferSize = 512;
3153 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3154 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00,
3155 0x04, 0x01, 0x00, 0x02};
3156
3157 auto responseMsg1 = new (requestUpdateResponse1.data()) pldm_msg;
3158
3159 struct pldm_request_downstream_device_update_resp resp_data1 = {
3160 .completion_code = 0,
3161 .downstream_device_meta_data_length = 0,
3162 .downstream_device_will_send_get_package_data = 0,
3163 .get_package_data_maximum_transfer_size = 0};
3164
3165 auto rc = decode_request_downstream_device_update_resp(
3166 responseMsg1, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3167 &resp_data1);
3168 EXPECT_EQ(rc, 0);
3169 EXPECT_EQ(resp_data1.completion_code, PLDM_SUCCESS);
3170 EXPECT_EQ(resp_data1.downstream_device_meta_data_length, ddMetaDataLen);
3171 EXPECT_EQ(resp_data1.downstream_device_will_send_get_package_data,
3172 ddWillSendPkgData);
3173 EXPECT_EQ(resp_data1.get_package_data_maximum_transfer_size,
3174 getPkgDataMaxTransferSize);
3175
3176 /* Test a failure completion code */
3177 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3178 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3179
3180 auto responseMsg2 = new (requestUpdateResponse2.data()) pldm_msg;
3181
3182 struct pldm_request_downstream_device_update_resp resp_data2 = {
3183 .completion_code = 0,
3184 .downstream_device_meta_data_length = 0,
3185 .downstream_device_will_send_get_package_data = 0,
3186 .get_package_data_maximum_transfer_size = 0};
3187
3188 rc = decode_request_downstream_device_update_resp(
3189 responseMsg2, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3190 &resp_data2);
3191 EXPECT_EQ(rc, 0);
3192 EXPECT_EQ(resp_data2.completion_code, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3193}
3194#endif // LIBPLDM_API_TESTING
3195
3196#ifdef LIBPLDM_API_TESTING
3197TEST(RequestDownstreamDeviceUpdate, errorPathDecodeResponse)
3198{
3199 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3200 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00,
3201 0x04, 0x01, 0x00, 0x02};
3202
3203 auto responseMsg = new (requestUpdateResponse.data()) pldm_msg;
3204
3205 struct pldm_request_downstream_device_update_resp resp_data = {
3206 .completion_code = 0,
3207 .downstream_device_meta_data_length = 0,
3208 .downstream_device_will_send_get_package_data = 0,
3209 .get_package_data_maximum_transfer_size = 0};
3210
3211 auto rc = decode_request_downstream_device_update_resp(
3212 nullptr, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, &resp_data);
3213 EXPECT_EQ(rc, -EINVAL);
3214
3215 rc = decode_request_downstream_device_update_resp(
3216 responseMsg, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, nullptr);
3217 EXPECT_EQ(rc, -EINVAL);
3218
3219 rc = decode_request_downstream_device_update_resp(responseMsg, 0,
3220 &resp_data);
3221 EXPECT_EQ(rc, -EOVERFLOW);
3222}
3223#endif // LIBPLDM_API_TESTING
3224
Andrew Jeffery9c766792022-08-10 23:12:49 +09303225TEST(PassComponentTable, goodPathEncodeRequest)
3226{
3227 constexpr uint8_t instanceId = 1;
3228 constexpr uint16_t compIdentifier = 400;
3229 constexpr uint8_t compClassificationIndex = 40;
3230 constexpr uint32_t compComparisonStamp = 0x12345678;
3231 constexpr std::string_view compVerStr = "0penBmcv1.1";
3232 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3233 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303234 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303235 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3236 compVerStrInfo.length = compVerStrLen;
3237
3238 std::array<uint8_t,
3239 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3240 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303241 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303242 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3243
3244 auto rc = encode_pass_component_table_req(
3245 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3246 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3247 compVerStrLen, &compVerStrInfo, requestMsg,
3248 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3249 EXPECT_EQ(rc, PLDM_SUCCESS);
3250
3251 std::array<uint8_t,
3252 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003253 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
3254 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
3255 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303256 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003257
3258#ifdef LIBPLDM_API_TESTING
3259 /* Check the roundtrip */
3260 struct pldm_pass_component_table_req_full req;
3261 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3262 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3263 rc =
3264 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
3265 ASSERT_EQ(rc, 0);
3266
3267 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
3268 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3269 EXPECT_EQ(req.comp_identifier, compIdentifier);
3270 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3271 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3272 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3273 EXPECT_EQ(req.version.str_len, compVerStrLen);
3274 EXPECT_TRUE(std::equal(req.version.str_data,
3275 req.version.str_data + req.version.str_len,
3276 compVerStr.data()));
3277#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303278}
3279
3280TEST(PassComponentTable, errorPathEncodeRequest)
3281{
3282 constexpr uint8_t instanceId = 1;
3283 constexpr uint16_t compIdentifier = 400;
3284 constexpr uint8_t compClassificationIndex = 40;
3285 constexpr uint32_t compComparisonStamp = 0x12345678;
3286 constexpr std::string_view compVerStr = "0penBmcv1.1";
3287 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3288 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303289 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303290 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3291 compVerStrInfo.length = compVerStrLen;
3292
3293 std::array<uint8_t,
3294 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3295 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303296 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303297 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3298
3299 auto rc = encode_pass_component_table_req(
3300 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3301 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3302 compVerStrLen, nullptr, requestMsg,
3303 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3304 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3305
3306 compVerStrInfo.ptr = nullptr;
3307 rc = encode_pass_component_table_req(
3308 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3309 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3310 compVerStrLen, &compVerStrInfo, requestMsg,
3311 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3312 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303313 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303314 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3315
3316 rc = encode_pass_component_table_req(
3317 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3318 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3319 compVerStrLen, &compVerStrInfo, nullptr,
3320 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3321 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3322
3323 rc = encode_pass_component_table_req(
3324 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3325 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3326 compVerStrLen, &compVerStrInfo, requestMsg,
3327 sizeof(pldm_pass_component_table_req));
3328 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3329
3330 rc = encode_pass_component_table_req(
3331 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3332 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3333 &compVerStrInfo, requestMsg,
3334 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3335 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3336
3337 rc = encode_pass_component_table_req(
3338 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3339 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3340 compVerStrLen - 1, &compVerStrInfo, requestMsg,
3341 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3342 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3343
3344 rc = encode_pass_component_table_req(
3345 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3346 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3347 compVerStrLen, &compVerStrInfo, requestMsg,
3348 sizeof(pldm_pass_component_table_req) + compVerStrLen);
Manojkiran Eda3643e742025-05-19 12:03:54 +05303349 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG);
Andrew Jeffery9c766792022-08-10 23:12:49 +09303350
3351 rc = encode_pass_component_table_req(
3352 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3353 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3354 compVerStrLen, &compVerStrInfo, requestMsg,
3355 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3356 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3357}
3358
3359TEST(PassComponentTable, goodPathDecodeResponse)
3360{
3361 constexpr std::array<uint8_t,
3362 hdrSize + sizeof(pldm_pass_component_table_resp)>
3363 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3364 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303365 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303366 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3367
3368 uint8_t completionCode = 0;
3369 uint8_t compResp = 0;
3370 uint8_t compRespCode = 0;
3371
3372 auto rc = decode_pass_component_table_resp(
3373 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3374 &compResp, &compRespCode);
3375
3376 EXPECT_EQ(rc, PLDM_SUCCESS);
3377 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3378 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3379 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3380
3381 constexpr std::array<uint8_t,
3382 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003383 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303384 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303385 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303386 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3387 rc = decode_pass_component_table_resp(
3388 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3389 &compResp, &compRespCode);
3390
3391 EXPECT_EQ(rc, PLDM_SUCCESS);
3392 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3393 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3394 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3395
3396 constexpr std::array<uint8_t,
3397 hdrSize + sizeof(pldm_pass_component_table_resp)>
3398 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3399 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303400 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303401 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3402
3403 rc = decode_pass_component_table_resp(
3404 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3405 &compResp, &compRespCode);
3406
3407 EXPECT_EQ(rc, PLDM_SUCCESS);
3408 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3409}
3410
3411TEST(PassComponentTable, errorPathDecodeResponse)
3412{
3413 constexpr std::array<uint8_t,
3414 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3415 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3416 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303417 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303418 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3419
3420 uint8_t completionCode = 0;
3421 uint8_t compResp = 0;
3422 uint8_t compRespCode = 0;
3423
3424 auto rc = decode_pass_component_table_resp(
3425 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3426 &compResp, &compRespCode);
3427 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3428
3429 rc = decode_pass_component_table_resp(
3430 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
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,
3436 &completionCode, nullptr, &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, &compResp, nullptr);
3442 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3443
3444 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3445 &compResp, &compRespCode);
3446 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3447
3448 rc = decode_pass_component_table_resp(
3449 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3450 &completionCode, &compResp, &compRespCode);
3451 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3452
3453 constexpr std::array<uint8_t,
3454 hdrSize + sizeof(pldm_pass_component_table_resp)>
3455 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3456 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303457 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303458 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3459 rc = decode_pass_component_table_resp(
3460 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3461 &compResp, &compRespCode);
3462 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3463
3464 constexpr std::array<uint8_t,
3465 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003466 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303467 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303468 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303469 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3470 rc = decode_pass_component_table_resp(
3471 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3472 &compResp, &compRespCode);
3473 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3474
3475 constexpr std::array<uint8_t,
3476 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003477 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303478 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303479 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303480 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3481 rc = decode_pass_component_table_resp(
3482 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3483 &compResp, &compRespCode);
3484 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3485}
3486
3487TEST(UpdateComponent, goodPathEncodeRequest)
3488{
3489 constexpr uint8_t instanceId = 2;
3490 constexpr uint16_t compIdentifier = 500;
3491 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003492 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303493 constexpr uint32_t compImageSize = 4096;
3494 constexpr bitfield32_t updateOptionFlags{1};
3495 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3496 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3497 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303498 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303499 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3500 compVerStrInfo.length = compVerStrLen;
3501
3502 std::array<uint8_t,
3503 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3504 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303505 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303506 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3507
3508 auto rc = encode_update_component_req(
3509 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3510 compComparisonStamp, compImageSize, updateOptionFlags,
3511 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3512 sizeof(pldm_update_component_req) + compVerStrLen);
3513 EXPECT_EQ(rc, PLDM_SUCCESS);
3514
3515 std::array<uint8_t,
3516 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003517 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3518 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3519 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3520 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303521 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003522
3523#ifdef LIBPLDM_API_TESTING
3524 /* Check the roundtrip */
3525 struct pldm_update_component_req_full req;
3526 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3527 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3528 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3529 ASSERT_EQ(rc, 0);
3530
3531 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3532 EXPECT_EQ(req.comp_identifier, compIdentifier);
3533 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3534 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3535 EXPECT_EQ(req.comp_image_size, compImageSize);
3536 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3537 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3538 EXPECT_EQ(req.version.str_len, compVerStrLen);
3539 EXPECT_TRUE(std::equal(req.version.str_data,
3540 req.version.str_data + req.version.str_len,
3541 compVerStr.data()));
3542#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303543}
3544
3545TEST(UpdateComponent, errorPathEncodeRequest)
3546{
3547 constexpr uint8_t instanceId = 2;
3548 constexpr uint16_t compIdentifier = 500;
3549 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003550 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303551 constexpr uint32_t compImageSize = 4096;
3552 constexpr bitfield32_t updateOptionFlags{1};
3553 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3554 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3555 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303556 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303557 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3558 compVerStrInfo.length = compVerStrLen;
3559
3560 std::array<uint8_t,
3561 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3562 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303563 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303564 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3565
3566 auto rc = encode_update_component_req(
3567 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3568 compComparisonStamp, compImageSize, updateOptionFlags,
3569 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3570 sizeof(pldm_update_component_req) + compVerStrLen);
3571 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3572
3573 compVerStrInfo.ptr = nullptr;
3574 rc = encode_update_component_req(
3575 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3576 compComparisonStamp, compImageSize, updateOptionFlags,
3577 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3578 sizeof(pldm_update_component_req) + compVerStrLen);
3579 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303580 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303581 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3582
3583 rc = encode_update_component_req(
3584 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3585 compComparisonStamp, compImageSize, updateOptionFlags,
3586 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3587 sizeof(pldm_update_component_req) + compVerStrLen);
3588 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3589
3590 rc = encode_update_component_req(
3591 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3592 compComparisonStamp, compImageSize, updateOptionFlags,
3593 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3594 sizeof(pldm_update_component_req));
3595 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3596
3597 rc = encode_update_component_req(
3598 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3599 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3600 compVerStrLen, &compVerStrInfo, requestMsg,
3601 sizeof(pldm_update_component_req) + compVerStrLen);
3602 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3603
3604 rc = encode_update_component_req(
3605 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3606 compComparisonStamp, compImageSize, updateOptionFlags,
3607 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3608 sizeof(pldm_update_component_req) + compVerStrLen);
3609 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3610
3611 rc = encode_update_component_req(
3612 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3613 compComparisonStamp, compImageSize, updateOptionFlags,
3614 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3615 sizeof(pldm_update_component_req) + compVerStrLen);
3616 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3617
3618 rc = encode_update_component_req(
3619 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3620 compComparisonStamp, compImageSize, updateOptionFlags,
3621 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3622 sizeof(pldm_update_component_req) + compVerStrLen);
3623 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3624}
3625
3626TEST(UpdateComponent, goodPathDecodeResponse)
3627{
3628 constexpr std::bitset<32> forceUpdateComp{1};
3629 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3630 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3631 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3632 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3633 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303634 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303635 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3636
3637 uint8_t completionCode = 0;
3638 uint8_t compCompatibilityResp = 0;
3639 uint8_t compCompatibilityRespCode = 0;
3640 bitfield32_t updateOptionFlagsEnabled{};
3641 uint16_t timeBeforeReqFWData = 0;
3642
3643 auto rc = decode_update_component_resp(
3644 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3645 &compCompatibilityResp, &compCompatibilityRespCode,
3646 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3647
3648 EXPECT_EQ(rc, PLDM_SUCCESS);
3649 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3650 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3651 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3652 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3653 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3654
3655 constexpr std::bitset<32> noFlags{};
3656 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3657 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3658 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3660 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303661 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303662 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3663 rc = decode_update_component_resp(
3664 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3665 &compCompatibilityResp, &compCompatibilityRespCode,
3666 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3667
3668 EXPECT_EQ(rc, PLDM_SUCCESS);
3669 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3670 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3671 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3672 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3673 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3674
3675 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3676 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3677 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303678 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303679 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3680
3681 rc = decode_update_component_resp(
3682 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3683 &compCompatibilityResp, &compCompatibilityRespCode,
3684 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3685
3686 EXPECT_EQ(rc, PLDM_SUCCESS);
3687 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3688}
3689
3690TEST(UpdateComponent, errorPathDecodeResponse)
3691{
3692 constexpr std::array<uint8_t,
3693 hdrSize + sizeof(pldm_update_component_resp) - 1>
3694 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3695 0x00, 0x00, 0x00, 0x00, 0x00};
3696 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303697 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303698 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3699
3700 uint8_t completionCode = 0;
3701 uint8_t compCompatibilityResp = 0;
3702 uint8_t compCompatibilityRespCode = 0;
3703 bitfield32_t updateOptionFlagsEnabled{};
3704 uint16_t timeBeforeReqFWData = 0;
3705
3706 auto rc = decode_update_component_resp(
3707 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3708 &compCompatibilityResp, &compCompatibilityRespCode,
3709 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3710 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3711
3712 rc = decode_update_component_resp(
3713 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3714 &compCompatibilityResp, &compCompatibilityRespCode,
3715 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3716 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3717
3718 rc = decode_update_component_resp(
3719 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3720 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3721 &timeBeforeReqFWData);
3722 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3723
3724 rc = decode_update_component_resp(
3725 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3726 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3727 &timeBeforeReqFWData);
3728 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3729
3730 rc = decode_update_component_resp(
3731 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3732 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3733 &timeBeforeReqFWData);
3734 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3735
3736 rc = decode_update_component_resp(
3737 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3738 &compCompatibilityResp, &compCompatibilityRespCode,
3739 &updateOptionFlagsEnabled, nullptr);
3740 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3741
3742 rc = decode_update_component_resp(
3743 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3744 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3745 &timeBeforeReqFWData);
3746 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3747
3748 rc = decode_update_component_resp(
3749 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3750 &compCompatibilityResp, &compCompatibilityRespCode,
3751 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3752 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3753
3754 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3755 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3756 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3757 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303758 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303759 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3760 rc = decode_update_component_resp(
3761 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3762 &compCompatibilityResp, &compCompatibilityRespCode,
3763 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3764 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3765
3766 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003767 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303768 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3769 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303770 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303771 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3772 rc = decode_update_component_resp(
3773 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3774 &compCompatibilityResp, &compCompatibilityRespCode,
3775 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3776 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3777
3778 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003779 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303780 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3781 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303782 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303783 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3784 rc = decode_update_component_resp(
3785 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3786 &compCompatibilityResp, &compCompatibilityRespCode,
3787 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3788 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3789}
3790
3791TEST(RequestFirmwareData, goodPathDecodeRequest)
3792{
3793 constexpr uint32_t offset = 300;
3794 constexpr uint32_t length = 255;
3795 constexpr std::array<uint8_t,
3796 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003797 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3798 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303799 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303800 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3801
3802 uint32_t outOffset = 0;
3803 uint32_t outLength = 0;
3804 auto rc = decode_request_firmware_data_req(
3805 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3806 &outLength);
3807
3808 EXPECT_EQ(rc, PLDM_SUCCESS);
3809 EXPECT_EQ(outOffset, offset);
3810 EXPECT_EQ(outLength, length);
3811}
3812
3813TEST(RequestFirmwareData, errorPathDecodeRequest)
3814{
3815 constexpr std::array<uint8_t,
3816 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003817 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3818 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303819 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303820 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3821
3822 uint32_t outOffset = 0;
3823 uint32_t outLength = 0;
3824 auto rc = decode_request_firmware_data_req(
3825 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3826 &outLength);
3827 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3828
3829 rc = decode_request_firmware_data_req(
3830 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
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), &outOffset,
3836 nullptr);
3837 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3838
3839 rc = decode_request_firmware_data_req(
3840 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3841 &outLength);
3842 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3843
3844 rc = decode_request_firmware_data_req(
3845 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3846 &outLength);
3847 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3848}
3849
3850TEST(RequestFirmwareData, goodPathEncodeResponse)
3851{
3852 constexpr uint8_t instanceId = 3;
3853 constexpr uint8_t completionCode = PLDM_SUCCESS;
3854 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3855 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3856 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003857 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3858 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3859 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3860 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303861 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3862 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3863 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003864 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3865 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3866 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3867 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303868 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303869 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3870 auto rc = encode_request_firmware_data_resp(
3871 instanceId, completionCode, responseMsg1,
3872 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3873 EXPECT_EQ(rc, PLDM_SUCCESS);
3874 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3875
3876 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3877 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3878 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3879 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303880 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303881 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3882 rc = encode_request_firmware_data_resp(
3883 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3884 sizeof(completionCode));
3885 EXPECT_EQ(rc, PLDM_SUCCESS);
3886 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3887}
3888
3889TEST(RequestFirmwareData, errorPathEncodeResponse)
3890{
3891 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303892 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303893 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3894 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3895 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3896
3897 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3898 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3899}
3900
3901TEST(TransferComplete, goodPathDecodeRequest)
3902{
3903 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3904 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3905 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3906 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303907 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303908 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3909 uint8_t outTransferResult = 0;
3910
3911 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3912 &outTransferResult);
3913 EXPECT_EQ(rc, PLDM_SUCCESS);
3914 EXPECT_EQ(outTransferResult, transferResult);
3915
3916 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3917 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3918 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303919 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303920 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3921 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3922 &outTransferResult);
3923 EXPECT_EQ(rc, PLDM_SUCCESS);
3924 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3925}
3926
3927TEST(TransferComplete, errorPathDecodeRequest)
3928{
3929 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3930 0x00};
3931 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303932 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303933 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3934 uint8_t outTransferResult = 0;
3935
3936 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3937 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3938
3939 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3940 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3941
3942 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3943 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3944}
3945
3946TEST(TransferComplete, goodPathEncodeResponse)
3947{
3948 constexpr uint8_t instanceId = 4;
3949 constexpr uint8_t completionCode = PLDM_SUCCESS;
3950 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3951 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3952 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3953 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3954 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303955 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303956 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3957 auto rc = encode_transfer_complete_resp(
3958 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3959 EXPECT_EQ(rc, PLDM_SUCCESS);
3960 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3961
3962 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3963 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3964 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3965 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3966 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303967 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303968 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3969 rc = encode_transfer_complete_resp(instanceId,
3970 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3971 responseMsg2, sizeof(completionCode));
3972 EXPECT_EQ(rc, PLDM_SUCCESS);
3973 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3974}
3975
3976TEST(TransferComplete, errorPathEncodeResponse)
3977{
3978 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3979 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303980 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303981 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3982 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3983 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3984
3985 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3986 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3987}
3988
3989TEST(VerifyComplete, goodPathDecodeRequest)
3990{
3991 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3992 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3993 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3994 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303995 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303996 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3997 uint8_t outVerifyResult = 0;
3998
3999 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
4000 &outVerifyResult);
4001 EXPECT_EQ(rc, PLDM_SUCCESS);
4002 EXPECT_EQ(outVerifyResult, verifyResult);
4003
4004 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
4005 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
4006 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304007 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304008 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
4009 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
4010 &outVerifyResult);
4011 EXPECT_EQ(rc, PLDM_SUCCESS);
4012 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
4013}
4014
4015TEST(VerifyComplete, errorPathDecodeRequest)
4016{
4017 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
4018 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304019 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304020 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
4021 uint8_t outVerifyResult = 0;
4022
4023 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
4024 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4025
4026 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
4027 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4028
4029 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
4030 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4031}
4032
4033TEST(VerifyComplete, goodPathEncodeResponse)
4034{
4035 constexpr uint8_t instanceId = 5;
4036 constexpr uint8_t completionCode = PLDM_SUCCESS;
4037 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4038 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
4039 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4040 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4041 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304042 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304043 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
4044 auto rc = encode_verify_complete_resp(instanceId, completionCode,
4045 responseMsg1, sizeof(completionCode));
4046 EXPECT_EQ(rc, PLDM_SUCCESS);
4047 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
4048
4049 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4050 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
4051 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4052 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4053 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304054 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304055 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
4056 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4057 responseMsg2, sizeof(completionCode));
4058 EXPECT_EQ(rc, PLDM_SUCCESS);
4059 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
4060}
4061
4062TEST(VerifyComplete, errorPathEncodeResponse)
4063{
4064 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
4065 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304066 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304067 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
4068 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4069 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4070
4071 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4072 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4073}
4074
4075TEST(ApplyComplete, goodPathDecodeRequest)
4076{
4077 constexpr uint8_t applyResult1 =
4078 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
4079 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
4080 constexpr std::bitset<16> compActivationModification1{0x30};
4081 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4082 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
4083 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304084 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304085 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4086 uint8_t outApplyResult = 0;
4087 bitfield16_t outCompActivationModification{};
4088 auto rc = decode_apply_complete_req(
4089 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
4090 &outCompActivationModification);
4091 EXPECT_EQ(rc, PLDM_SUCCESS);
4092 EXPECT_EQ(outApplyResult, applyResult1);
4093 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
4094
4095 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
4096 constexpr std::bitset<16> compActivationModification2{};
4097 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4098 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4099 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304100 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304101 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4102 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4103 &outApplyResult,
4104 &outCompActivationModification);
4105 EXPECT_EQ(rc, PLDM_SUCCESS);
4106 EXPECT_EQ(outApplyResult, applyResult2);
4107 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
4108}
4109
4110TEST(ApplyComplete, errorPathDecodeRequest)
4111{
4112 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
4113 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304114 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304115 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4116 uint8_t outApplyResult = 0;
4117 bitfield16_t outCompActivationModification{};
4118
4119 auto rc = decode_apply_complete_req(
4120 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
4121 &outCompActivationModification);
4122 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4123
4124 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4125 nullptr, &outCompActivationModification);
4126 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4127
4128 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4129 &outApplyResult, nullptr);
4130 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4131
4132 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
4133 &outCompActivationModification);
4134 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4135
4136 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4137 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
4138 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304139 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304140 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4141 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4142 &outApplyResult,
4143 &outCompActivationModification);
4144 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4145}
4146
4147TEST(ApplyComplete, goodPathEncodeResponse)
4148{
4149 constexpr uint8_t instanceId = 6;
4150 constexpr uint8_t completionCode = PLDM_SUCCESS;
4151 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4152 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
4153 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4154 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4155 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304156 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304157 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
4158 auto rc = encode_apply_complete_resp(instanceId, completionCode,
4159 responseMsg1, sizeof(completionCode));
4160 EXPECT_EQ(rc, PLDM_SUCCESS);
4161 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
4162
4163 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4164 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
4165 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4166 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4167 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304168 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304169 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
4170 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4171 responseMsg2, sizeof(completionCode));
4172 EXPECT_EQ(rc, PLDM_SUCCESS);
4173 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
4174}
4175
4176TEST(ApplyComplete, errorPathEncodeResponse)
4177{
4178 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
4179 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304180 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304181 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
4182 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4183 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4184
4185 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4186 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4187}
4188
4189TEST(ActivateFirmware, goodPathEncodeRequest)
4190{
4191 constexpr uint8_t instanceId = 7;
4192
4193 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304194 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304195 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4196
4197 auto rc = encode_activate_firmware_req(
4198 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
4199 sizeof(pldm_activate_firmware_req));
4200 EXPECT_EQ(rc, PLDM_SUCCESS);
4201
4202 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004203 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304204 EXPECT_EQ(request, outRequest);
4205}
4206
4207TEST(ActivateFirmware, errorPathEncodeRequest)
4208{
4209 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304210 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304211 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4212
4213 auto rc = encode_activate_firmware_req(
4214 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
4215 sizeof(pldm_activate_firmware_req));
4216 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4217
4218 rc = encode_activate_firmware_req(
4219 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
4220 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4221
4222 rc = encode_activate_firmware_req(0, 2, requestMsg,
4223 sizeof(pldm_activate_firmware_req));
4224 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4225}
4226
4227TEST(ActivateFirmware, goodPathDecodeResponse)
4228{
4229 constexpr uint16_t estimatedTimeForActivation100s = 100;
4230 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4231 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
4232 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304233 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304234 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
4235
4236 uint8_t completionCode = 0;
4237 uint16_t estimatedTimeForActivation = 0;
4238
4239 auto rc = decode_activate_firmware_resp(
4240 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
4241 &estimatedTimeForActivation);
4242
4243 EXPECT_EQ(rc, PLDM_SUCCESS);
4244 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4245 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
4246
4247 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4248 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
4249 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304250 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304251 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
4252
4253 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
4254 &completionCode,
4255 &estimatedTimeForActivation);
4256
4257 EXPECT_EQ(rc, PLDM_SUCCESS);
4258 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
4259}
4260
4261TEST(ActivateFirmware, errorPathDecodeResponse)
4262{
4263 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4264 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4265 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304266 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304267 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
4268
4269 uint8_t completionCode = 0;
4270 uint16_t estimatedTimeForActivation = 0;
4271
4272 auto rc = decode_activate_firmware_resp(
4273 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
4274 &estimatedTimeForActivation);
4275 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4276
4277 rc = decode_activate_firmware_resp(responseMsg,
4278 sizeof(pldm_activate_firmware_resp),
4279 nullptr, &estimatedTimeForActivation);
4280 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4281
4282 rc = decode_activate_firmware_resp(responseMsg,
4283 sizeof(pldm_activate_firmware_resp),
4284 &completionCode, nullptr);
4285 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4286
4287 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
4288 &estimatedTimeForActivation);
4289 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4290
4291 rc = decode_activate_firmware_resp(
4292 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
4293 &estimatedTimeForActivation);
4294 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4295}
4296
4297TEST(GetStatus, goodPathEncodeRequest)
4298{
4299 constexpr uint8_t instanceId = 8;
4300 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304301 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304302 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4303
4304 auto rc = encode_get_status_req(instanceId, requestMsg,
4305 PLDM_GET_STATUS_REQ_BYTES);
4306 EXPECT_EQ(rc, PLDM_SUCCESS);
4307
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004308 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304309 EXPECT_EQ(request, outRequest);
4310}
4311
4312TEST(GetStatus, errorPathEncodeRequest)
4313{
4314 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304315 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304316 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4317
4318 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4319 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4320
4321 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4322 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4323}
4324
4325TEST(GetStatus, goodPathDecodeResponse)
4326{
4327 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4328 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4329 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4330 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4331 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304332 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304333 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4334
4335 uint8_t completionCode = 0;
4336 uint8_t currentState = 0;
4337 uint8_t previousState = 0;
4338 uint8_t auxState = 0;
4339 uint8_t auxStateStatus = 0;
4340 uint8_t progressPercent = 0;
4341 uint8_t reasonCode = 0;
4342 bitfield32_t updateOptionFlagsEnabled{0};
4343
4344 auto rc = decode_get_status_resp(
4345 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4346 &currentState, &previousState, &auxState, &auxStateStatus,
4347 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4348
4349 EXPECT_EQ(rc, PLDM_SUCCESS);
4350 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4351 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4352 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4353 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4354 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4355 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4356 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4357 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4358
4359 // Bit position 0 - Force update of component – FD will perform a force
4360 // update of the component.
4361 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4362 constexpr uint8_t progressPercent2 = 50;
4363 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4364 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4365 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4366 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304367 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304368 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4369
4370 rc = decode_get_status_resp(
4371 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4372 &currentState, &previousState, &auxState, &auxStateStatus,
4373 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4374
4375 EXPECT_EQ(rc, PLDM_SUCCESS);
4376 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4377 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4378 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4379 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4380 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4381 EXPECT_EQ(progressPercent, progressPercent2);
4382 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4383 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4384
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004385#ifdef LIBPLDM_API_TESTING
4386 /* Check the roundtrip */
4387 PLDM_MSG_DEFINE_P(enc, 1000);
4388 size_t enc_payload_len = 1000;
4389 const struct pldm_get_status_resp status_enc = {
4390 .completion_code = PLDM_SUCCESS,
4391 .current_state = currentState,
4392 .previous_state = previousState,
4393 .aux_state = auxState,
4394 .aux_state_status = auxStateStatus,
4395 .progress_percent = progressPercent,
4396 .reason_code = reasonCode,
4397 .update_option_flags_enabled = updateOptionFlagsEnabled,
4398 };
4399 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4400 &enc_payload_len);
4401 EXPECT_EQ(rc, PLDM_SUCCESS);
4402 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4403 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4404 getStatusResponse2.end(), enc_buf + hdrSize));
4405 check_response(enc, PLDM_GET_STATUS);
4406#endif
4407
4408 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304409 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4410 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4411 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304412 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304413 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4414 rc = decode_get_status_resp(
4415 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4416 &currentState, &previousState, &auxState, &auxStateStatus,
4417 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4418 EXPECT_EQ(rc, PLDM_SUCCESS);
4419 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4420}
4421
4422TEST(GetStatus, errorPathDecodeResponse)
4423{
4424 uint8_t completionCode = 0;
4425 uint8_t currentState = 0;
4426 uint8_t previousState = 0;
4427 uint8_t auxState = 0;
4428 uint8_t auxStateStatus = 0;
4429 uint8_t progressPercent = 0;
4430 uint8_t reasonCode = 0;
4431 bitfield32_t updateOptionFlagsEnabled{0};
4432
4433 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4434 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304435 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304436 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4437
4438 auto rc = decode_get_status_resp(
4439 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4440 &currentState, &previousState, &auxState, &auxStateStatus,
4441 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4442 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4443
4444 rc = decode_get_status_resp(
4445 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4446 &currentState, &previousState, &auxState, &auxStateStatus,
4447 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4448 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4449
4450 rc = decode_get_status_resp(
4451 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4452 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4453 &reasonCode, &updateOptionFlagsEnabled);
4454 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4455
4456 rc = decode_get_status_resp(
4457 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4458 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4459 &reasonCode, &updateOptionFlagsEnabled);
4460 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4461
4462 rc = decode_get_status_resp(
4463 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4464 &currentState, &previousState, nullptr, &auxStateStatus,
4465 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4466 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4467
4468 rc = decode_get_status_resp(
4469 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4470 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4471 &reasonCode, &updateOptionFlagsEnabled);
4472 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4473
4474 rc = decode_get_status_resp(
4475 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4476 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4477 &reasonCode, &updateOptionFlagsEnabled);
4478 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4479
4480 rc = decode_get_status_resp(
4481 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4482 &currentState, &previousState, &auxState, &auxStateStatus,
4483 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4484 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4485
4486 rc = decode_get_status_resp(
4487 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4488 &currentState, &previousState, &auxState, &auxStateStatus,
4489 &progressPercent, &reasonCode, nullptr);
4490 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4491
4492 rc = decode_get_status_resp(
4493 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4494 &currentState, &previousState, &auxState, &auxStateStatus,
4495 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4496 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4497
4498 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4499 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4501 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304502 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304503 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4504 rc = decode_get_status_resp(
4505 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4506 &currentState, &previousState, &auxState, &auxStateStatus,
4507 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4508 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4509
4510 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4511 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4513 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304514 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304515 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4516 rc = decode_get_status_resp(
4517 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4518 &currentState, &previousState, &auxState, &auxStateStatus,
4519 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4520 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4521
4522 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4523 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4524 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4525 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304526 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304527 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4528 rc = decode_get_status_resp(
4529 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4530 &currentState, &previousState, &auxState, &auxStateStatus,
4531 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4532 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4533
4534 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4535 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4537 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304538 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304539 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4540 rc = decode_get_status_resp(
4541 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4542 &currentState, &previousState, &auxState, &auxStateStatus,
4543 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4544 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4545
4546 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4547 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004548 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304549 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304550 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304551 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4552 rc = decode_get_status_resp(
4553 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4554 &currentState, &previousState, &auxState, &auxStateStatus,
4555 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4556 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4557
4558 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4559 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4560 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4561 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304562 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304563 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4564 rc = decode_get_status_resp(
4565 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4566 &currentState, &previousState, &auxState, &auxStateStatus,
4567 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4568 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4569
4570 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4571 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004572 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304573 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304574 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304575 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4576 rc = decode_get_status_resp(
4577 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4578 &currentState, &previousState, &auxState, &auxStateStatus,
4579 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4580 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4581
4582 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4583 // IDLE
4584 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4585 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4587 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304588 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304589 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4590 rc = decode_get_status_resp(
4591 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4592 &currentState, &previousState, &auxState, &auxStateStatus,
4593 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4594 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4595}
4596
4597TEST(CancelUpdateComponent, goodPathEncodeRequest)
4598{
4599 constexpr uint8_t instanceId = 9;
4600 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304601 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304602 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4603
4604 auto rc = encode_cancel_update_component_req(
4605 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4606 EXPECT_EQ(rc, PLDM_SUCCESS);
4607
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004608 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304609 EXPECT_EQ(request, outRequest);
4610}
4611
4612TEST(CancelUpdateComponent, errorPathEncodeRequest)
4613{
4614 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304615 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304616 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4617
4618 auto rc = encode_cancel_update_component_req(
4619 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4620 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4621
4622 rc = encode_cancel_update_component_req(
4623 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4624 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4625}
4626
4627TEST(CancelUpdateComponent, testGoodDecodeResponse)
4628{
4629 uint8_t completionCode = 0;
4630 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4631 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304632 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304633 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4634 cancelUpdateComponentResponse1.data());
4635 auto rc = decode_cancel_update_component_resp(
4636 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4637 &completionCode);
4638 EXPECT_EQ(rc, PLDM_SUCCESS);
4639 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4640
4641 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4642 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304643 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304644 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4645 cancelUpdateComponentResponse2.data());
4646 rc = decode_cancel_update_component_resp(
4647 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4648 &completionCode);
4649 EXPECT_EQ(rc, PLDM_SUCCESS);
4650 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4651}
4652
4653TEST(CancelUpdateComponent, testBadDecodeResponse)
4654{
4655 uint8_t completionCode = 0;
4656 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4657 0x00, 0x00, 0x00};
4658 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304659 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304660 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4661
4662 auto rc = decode_cancel_update_component_resp(
4663 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4664 &completionCode);
4665 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4666
4667 rc = decode_cancel_update_component_resp(
4668 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4669 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4670
4671 rc = decode_cancel_update_component_resp(
4672 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4673 &completionCode);
4674 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4675}
4676
4677TEST(CancelUpdate, goodPathEncodeRequest)
4678{
4679 constexpr uint8_t instanceId = 10;
4680 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304681 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304682 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4683
4684 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4685 PLDM_CANCEL_UPDATE_REQ_BYTES);
4686 EXPECT_EQ(rc, PLDM_SUCCESS);
4687
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004688 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304689 EXPECT_EQ(request, outRequest);
4690}
4691
4692TEST(CancelUpdate, errorPathEncodeRequest)
4693{
4694 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304695 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304696 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4697
4698 auto rc =
4699 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4700 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4701
4702 rc = encode_cancel_update_req(0, requestMsg,
4703 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4704 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4705}
4706
4707TEST(CancelUpdate, goodPathDecodeResponse)
4708{
4709 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4710 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4711 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4713 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304714 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304715 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4716 uint8_t completionCode = 0;
4717 bool8_t nonFunctioningComponentIndication = 0;
4718 bitfield64_t nonFunctioningComponentBitmap{0};
4719 auto rc = decode_cancel_update_resp(
4720 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4721 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4722 EXPECT_EQ(rc, PLDM_SUCCESS);
4723 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4724 EXPECT_EQ(nonFunctioningComponentIndication,
4725 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4726 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4727 nonFunctioningComponentBitmap1);
4728
4729 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4730 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4731 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4733 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304734 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304735 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4736 rc = decode_cancel_update_resp(
4737 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4738 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4739 EXPECT_EQ(rc, PLDM_SUCCESS);
4740 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4741 EXPECT_EQ(nonFunctioningComponentIndication,
4742 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4743 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4744 nonFunctioningComponentBitmap2);
4745
4746 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4747 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4748 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304749 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304750 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4751 rc = decode_cancel_update_resp(
4752 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4753 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4754 EXPECT_EQ(rc, PLDM_SUCCESS);
4755 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4756}
4757
4758TEST(CancelUpdate, errorPathDecodeResponse)
4759{
4760 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4761 0x00};
4762 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304763 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304764 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4765 uint8_t completionCode = 0;
4766 bool8_t nonFunctioningComponentIndication = 0;
4767 bitfield64_t nonFunctioningComponentBitmap{0};
4768
4769 auto rc = decode_cancel_update_resp(
4770 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4771 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4772 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4773
4774 rc = decode_cancel_update_resp(
4775 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4776 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4777 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4778
4779 rc = decode_cancel_update_resp(
4780 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4781 nullptr, &nonFunctioningComponentBitmap);
4782 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4783
4784 rc = decode_cancel_update_resp(
4785 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4786 &nonFunctioningComponentIndication, nullptr);
4787 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4788
4789 rc = decode_cancel_update_resp(
4790 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4791 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4792 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4793
4794 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4795 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4796 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304797 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304798 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4799 rc = decode_cancel_update_resp(
4800 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4801 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4802 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4803
4804 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4805 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4807 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304808 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304809 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4810 rc = decode_cancel_update_resp(
4811 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4812 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4813 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4814}
Andrew Jeffery2613c272025-03-12 14:15:41 +10304815
4816#ifdef LIBPLDM_API_TESTING
4817TEST(DecodePldmFirmwareUpdatePackage, badArguments)
4818{
4819 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
4820 pldm_package_header_information_pad hdr;
4821 struct pldm_package_iter iter;
4822 uint8_t data;
4823 int rc;
4824
4825 rc = decode_pldm_firmware_update_package(nullptr, 0, &pin, &hdr, &iter);
4826 EXPECT_EQ(rc, -EINVAL);
4827
4828 rc = decode_pldm_firmware_update_package(&data, sizeof(data), nullptr, &hdr,
4829 &iter);
4830 EXPECT_EQ(rc, -EINVAL);
4831
4832 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, nullptr,
4833 &iter);
4834 EXPECT_EQ(rc, -EINVAL);
4835
4836 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4837 nullptr);
4838 EXPECT_EQ(rc, -EINVAL);
4839}
4840#endif
4841
4842#ifdef LIBPLDM_API_TESTING
4843TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinVersion)
4844{
4845 const struct pldm_package_format_pin pin = {
4846 .meta =
4847 {
4848 .magic = 0,
4849 .version = UINT8_MAX,
4850 },
4851 .format =
4852 {
4853 .identifier = {0},
4854 .revision = 0,
4855 },
4856 };
4857
4858 pldm_package_header_information_pad hdr;
4859 struct pldm_package_iter iter;
4860 uint8_t data = 0;
4861 int rc;
4862
4863 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4864 &iter);
4865 EXPECT_EQ(rc, -ENOTSUP);
4866}
4867#endif
4868
4869#ifdef LIBPLDM_API_TESTING
4870TEST(DecodePldmFirmwareUpdatePackage, badPinRevision)
4871{
4872 const struct pldm_package_format_pin lowPin = {
4873 .meta =
4874 {
4875 .magic = 0,
4876 .version = 0,
4877 },
4878 .format =
4879 {
4880 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4881 .revision = 0,
4882 },
4883 };
4884
4885 const struct pldm_package_format_pin highPin = {
4886 .meta =
4887 {
4888 .magic = 0,
4889 .version = 0,
4890 },
4891 .format =
4892 {
4893 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4894 .revision = 3,
4895 },
4896 };
4897
4898 pldm_package_header_information_pad hdr;
4899 struct pldm_package_iter iter;
4900 uint8_t data = 0;
4901 int rc;
4902
4903 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4904 &iter);
4905 EXPECT_EQ(rc, -EINVAL);
4906
4907 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4908 &hdr, &iter);
4909 EXPECT_EQ(rc, -ENOTSUP);
4910}
4911#endif
4912
4913#ifdef LIBPLDM_API_TESTING
4914TEST(DecodePldmFirmwareUpdatePackage, badPinMagic)
4915{
4916 const struct pldm_package_format_pin lowPin = {
4917 .meta =
4918 {
4919 .magic = 0,
4920 .version = 0,
4921 },
4922 .format =
4923 {
4924 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4925 .revision = 2,
4926 },
4927 };
4928
4929 const struct pldm_package_format_pin highPin = {
4930 .meta =
4931 {
4932 .magic = UINT32_MAX,
4933 .version = 0,
4934 },
4935 .format =
4936 {
4937 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4938 .revision = 2,
4939 },
4940 };
4941
4942 pldm_package_header_information_pad hdr;
4943 struct pldm_package_iter iter;
4944 uint8_t data = 0;
4945 int rc;
4946
4947 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4948 &iter);
4949 EXPECT_EQ(rc, -EINVAL);
4950
4951 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4952 &hdr, &iter);
4953 EXPECT_EQ(rc, -EINVAL);
4954}
4955#endif
4956
4957#ifdef LIBPLDM_API_TESTING
4958TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinIdentifier)
4959{
4960 const struct pldm_package_format_pin pin = {
4961 .meta =
4962 {
4963 .magic =
4964 LIBPLDM_SIZEAT(struct pldm__package_header_information,
4965 package) +
4966 LIBPLDM_SIZEAT(
4967 struct pldm_package_firmware_device_id_record,
4968 firmware_device_package_data) +
4969 LIBPLDM_SIZEAT(struct pldm_descriptor, descriptor_data) +
4970 LIBPLDM_SIZEAT(
4971 struct pldm_package_downstream_device_id_record,
4972 package_data) +
4973 LIBPLDM_SIZEAT(
4974 struct pldm_package_component_image_information,
4975 component_version_string) +
4976 LIBPLDM_SIZEAT(struct pldm_package_iter, infos),
4977 .version = 0,
4978 },
4979 .format =
4980 {
4981 .identifier = {0},
4982 .revision = PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR02H,
4983 },
4984 };
4985
4986 pldm_package_header_information_pad hdr;
4987 struct pldm_package_iter iter;
4988 uint8_t data = 0;
4989 int rc;
4990
4991 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4992 &iter);
4993 EXPECT_EQ(rc, -ENOTSUP);
4994}
4995#endif
4996
4997#ifdef LIBPLDM_API_TESTING
4998TEST(DecodePldmFirmwareUpdatePackage, oldConsumer)
4999{
5000 /* Package format revision 2 header */
5001 const std::array<uint8_t, 150> package{
5002 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5003 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5004 0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5005 0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5006 };
5007
5008 /* Package format revision 1 consumer */
5009 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5010
5011 pldm_package_header_information_pad hdr;
5012 struct pldm_package_iter iter;
5013 int rc;
5014
5015 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5016 &pin, &hdr, &iter);
5017 EXPECT_EQ(rc, -ENOTSUP);
5018}
5019#endif
5020
5021#ifdef LIBPLDM_API_TESTING
5022TEST(DecodePldmFirmwareUpdatePackage, v1h1fd1fdd1cii)
5023{
5024 const std::array<uint8_t, 102> package{
5025 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5026 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5027 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5028 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5029
5030 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5031 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c,
5032 0x01, 0x00, 0x00,
5033
5034 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5035 0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5036 0x01, 0x04, 'v', '0', '.', '2', 0x00, 0x00, 0x00, 0x00,
5037
5038 0xb5, 0x3f, 0xf6, 0x6a,
5039
5040 0x5a,
5041 };
5042
5043 struct pldm_package_downstream_device_id_record ddrec;
5044 struct pldm_package_component_image_information info;
5045 struct pldm_package_firmware_device_id_record fdrec;
5046 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5047 pldm_package_header_information_pad hdr;
5048 struct pldm_package_iter iter;
5049 int nr_fdrec_desc = 0;
5050 int nr_ddrec_desc = 0;
5051 int nr_fdrec = 0;
5052 int nr_ddrec = 0;
5053 int nr_infos = 0;
5054 int rc;
5055
5056 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5057 &pin, &hdr, &iter);
5058 ASSERT_EQ(rc, 0);
5059
5060 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5061 hdr.package_header_identifier,
5062 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5063 0);
5064 EXPECT_EQ(hdr.package_header_format_revision, 1);
5065
5066 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5067 0x16, 0x03, 0x00, 0x00, 0x00,
5068 0x00, 0x76, 0x02};
5069 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5070 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5071 timestamp.size()),
5072 0);
5073
5074 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5075 EXPECT_EQ(hdr.package_version_string_type, 1);
5076 ASSERT_EQ(hdr.package_version_string.length, 4);
5077 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5078 hdr.package_version_string.length),
5079 0);
5080 EXPECT_NE(hdr.areas.ptr, nullptr);
5081 EXPECT_NE(hdr.areas.length, 0);
5082 EXPECT_NE(hdr.package.ptr, nullptr);
5083 EXPECT_NE(hdr.package.length, 0);
5084
5085 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5086 {
5087 struct pldm_descriptor desc;
5088
5089 EXPECT_EQ(fdrec.descriptor_count, 1);
5090 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5091 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5092 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5093 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5094 fdrec.component_image_set_version_string.length),
5095 0);
5096 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5097 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5098 EXPECT_NE(fdrec.record_descriptors.length, 0);
5099 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5100 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5101
5102 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5103 desc, rc)
5104 {
5105 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5106
5107 EXPECT_EQ(desc.descriptor_type, 1);
5108 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5109 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5110 sizeof(iana_pen_dmtf)),
5111 0);
5112
5113 nr_fdrec_desc++;
5114 }
5115 ASSERT_EQ(rc, 0);
5116
5117 nr_fdrec++;
5118 }
5119 ASSERT_EQ(rc, 0);
5120
5121 EXPECT_EQ(nr_fdrec, 1);
5122 EXPECT_EQ(nr_fdrec_desc, 1);
5123
5124 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5125 {
5126 struct pldm_descriptor desc;
5127
5128 EXPECT_EQ(ddrec.descriptor_count, 1);
5129 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5130 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5131 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5132 EXPECT_EQ(
5133 memcmp("v1.0",
5134 ddrec.self_contained_activation_min_version_string.ptr,
5135 ddrec.self_contained_activation_min_version_string.length),
5136 0);
5137 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5138 0);
5139 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5140 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5141 EXPECT_NE(ddrec.record_descriptors.length, 0);
5142 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5143 EXPECT_EQ(ddrec.package_data.length, 0);
5144
5145 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5146 desc, rc)
5147 {
5148 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5149
5150 EXPECT_EQ(desc.descriptor_type, 1);
5151 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5152 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5153 sizeof(iana_pen_dmtf)),
5154 0);
5155
5156 nr_ddrec_desc++;
5157 }
5158 ASSERT_EQ(rc, 0);
5159
5160 nr_ddrec++;
5161 }
5162 ASSERT_EQ(rc, 0);
5163
5164 EXPECT_EQ(nr_ddrec, 0);
5165 EXPECT_EQ(nr_ddrec_desc, 0);
5166
5167 static const pldm_package_component_image_information expected_info{
5168 0x000a, 0x0000, 0xffffffff, {0}, {1}, {nullptr, 1}, 0x01, {nullptr, 0}};
5169
5170 foreach_pldm_package_component_image_information(iter, info, rc)
5171 {
5172 EXPECT_EQ(info.component_classification,
5173 expected_info.component_classification);
5174 EXPECT_EQ(info.component_identifier,
5175 expected_info.component_identifier);
5176 EXPECT_EQ(info.component_comparison_stamp,
5177 expected_info.component_comparison_stamp);
5178 EXPECT_EQ(info.component_options.value,
5179 expected_info.component_options.value);
5180 EXPECT_EQ(info.requested_component_activation_method.value,
5181 expected_info.requested_component_activation_method.value);
5182 EXPECT_NE(nullptr, info.component_image.ptr);
5183 EXPECT_EQ(info.component_image.length,
5184 expected_info.component_image.length);
5185 EXPECT_EQ(info.component_version_string_type,
5186 expected_info.component_version_string_type);
5187 ASSERT_EQ(info.component_version_string.length, 4);
5188 EXPECT_EQ(memcmp("v0.2", info.component_version_string.ptr,
5189 info.component_version_string.length),
5190 0);
5191
5192 nr_infos++;
5193 }
5194 ASSERT_EQ(rc, 0);
5195
5196 EXPECT_EQ(nr_infos, 1);
5197}
5198#endif
5199
5200#ifdef LIBPLDM_API_TESTING
5201TEST(DecodePldmFirmwareUpdatePackage, v2h1fd1fdd1dd1ddd2cii)
5202{
5203 const std::array<uint8_t, 150> package{
5204 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5205 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5206 0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5207 0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5208
5209 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5210 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
5211 0x00, 0x9c, 0x01, 0x00, 0x00,
5212
5213 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5214 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
5215 0x00, 0x9c, 0x01, 0x00, 0x00,
5216
5217 0x02, 0x00,
5218
5219 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5220 0x01, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5221 0x01, 0x04, 'v', '0', '.', '2',
5222
5223 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5224 0x01, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5225 0x01, 0x04, 'v', '2', '.', '0',
5226
5227 0xd3, 0x5c, 0x1c, 0x8a,
5228
5229 0x5a,
5230
5231 0xa5,
5232 };
5233 struct pldm_package_downstream_device_id_record ddrec;
5234 struct pldm_package_component_image_information info;
5235 struct pldm_package_firmware_device_id_record fdrec;
5236 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5237 pldm_package_header_information_pad hdr;
5238 struct pldm_package_iter iter;
5239 int nr_fdrec_desc = 0;
5240 int nr_ddrec_desc = 0;
5241 int nr_fdrec = 0;
5242 int nr_ddrec = 0;
5243 int nr_infos = 0;
5244 int rc;
5245
5246 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5247 &pin, &hdr, &iter);
5248 ASSERT_EQ(rc, 0);
5249
5250 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.data(),
5251 hdr.package_header_identifier,
5252 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.size()),
5253 0);
5254 EXPECT_EQ(hdr.package_header_format_revision, 2);
5255
5256 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5257 0x16, 0x03, 0x00, 0x00, 0x00,
5258 0x00, 0x76, 0x02};
5259 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5260 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5261 timestamp.size()),
5262 0);
5263
5264 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5265 EXPECT_EQ(hdr.package_version_string_type, 1);
5266 ASSERT_EQ(hdr.package_version_string.length, 4);
5267 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5268 hdr.package_version_string.length),
5269 0);
5270 EXPECT_NE(hdr.areas.ptr, nullptr);
5271 EXPECT_NE(hdr.areas.length, 0);
5272 EXPECT_NE(hdr.package.ptr, nullptr);
5273 EXPECT_NE(hdr.package.length, 0);
5274
5275 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5276 {
5277 struct pldm_descriptor desc;
5278
5279 EXPECT_EQ(fdrec.descriptor_count, 1);
5280 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5281 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5282 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5283 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5284 fdrec.component_image_set_version_string.length),
5285 0);
5286 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5287 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5288 EXPECT_NE(fdrec.record_descriptors.length, 0);
5289 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5290 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5291
5292 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5293 desc, rc)
5294 {
5295 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5296
5297 EXPECT_EQ(desc.descriptor_type, 1);
5298 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5299 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5300 sizeof(iana_pen_dmtf)),
5301 0);
5302
5303 nr_fdrec_desc++;
5304 }
5305 ASSERT_EQ(rc, 0);
5306
5307 nr_fdrec++;
5308 }
5309 ASSERT_EQ(rc, 0);
5310
5311 EXPECT_EQ(nr_fdrec, 1);
5312 EXPECT_EQ(nr_fdrec_desc, 1);
5313
5314 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5315 {
5316 struct pldm_descriptor desc;
5317
5318 EXPECT_EQ(ddrec.descriptor_count, 1);
5319 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5320 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5321 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5322 EXPECT_EQ(
5323 memcmp("v1.0",
5324 ddrec.self_contained_activation_min_version_string.ptr,
5325 ddrec.self_contained_activation_min_version_string.length),
5326 0);
5327 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5328 0);
5329 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5330 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5331 EXPECT_NE(ddrec.record_descriptors.length, 0);
5332 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5333 EXPECT_EQ(ddrec.package_data.length, 0);
5334
5335 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5336 desc, rc)
5337 {
5338 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5339
5340 EXPECT_EQ(desc.descriptor_type, 1);
5341 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5342 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5343 sizeof(iana_pen_dmtf)),
5344 0);
5345
5346 nr_ddrec_desc++;
5347 }
5348 ASSERT_EQ(rc, 0);
5349
5350 nr_ddrec++;
5351 }
5352 ASSERT_EQ(rc, 0);
5353
5354 EXPECT_EQ(nr_ddrec, 1);
5355 EXPECT_EQ(nr_ddrec_desc, 1);
5356
5357 static const std::array<const char*, 2> component_versions = {
5358 "v0.2",
5359 "v2.0",
5360 };
5361 static const std::array<pldm_package_component_image_information, 2>
5362 expected_infos{{{0x000a,
5363 0x0000,
5364 0xffffffff,
5365 {0},
5366 {1},
5367 {nullptr, 1},
5368 0x01,
5369 {nullptr, 0}},
5370 {0x000a,
5371 0x0000,
5372 0xffffffff,
5373 {0},
5374 {1},
5375 {nullptr, 1},
5376 0x01,
5377 {nullptr, 0}}}};
5378 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5379
5380 foreach_pldm_package_component_image_information(iter, info, rc)
5381 {
5382 const struct pldm_package_component_image_information* expected;
5383 const char* version;
5384 uint8_t image;
5385
5386 expected = &expected_infos.at(nr_infos);
5387 version = component_versions.at(nr_infos);
5388 image = expected_images.at(nr_infos);
5389
5390 EXPECT_EQ(info.component_classification,
5391 expected->component_classification);
5392 EXPECT_EQ(info.component_identifier, expected->component_identifier);
5393 EXPECT_EQ(info.component_comparison_stamp,
5394 expected->component_comparison_stamp);
5395 EXPECT_EQ(info.component_options.value,
5396 expected->component_options.value);
5397 EXPECT_EQ(info.requested_component_activation_method.value,
5398 expected->requested_component_activation_method.value);
5399 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5400 EXPECT_EQ(info.component_image.length,
5401 expected->component_image.length);
5402 EXPECT_EQ(*info.component_image.ptr, image);
5403 EXPECT_EQ(info.component_version_string_type,
5404 expected->component_version_string_type);
5405 ASSERT_EQ(info.component_version_string.length, 4);
5406 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5407 info.component_version_string.length),
5408 0);
5409
5410 nr_infos++;
5411 }
5412 ASSERT_EQ(rc, 0);
5413
5414 EXPECT_EQ(nr_infos, 2);
5415}
5416#endif