blob: 21b65ca07e7588e6b60a3b00d9a85a99bc5e1f1e [file] [log] [blame]
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05301#include <endian.h>
Andrew Jefferyb0c1d202023-11-07 22:08:44 +10302#include <libpldm/base.h>
3#include <libpldm/firmware_update.h>
4#include <libpldm/pldm_types.h>
5#include <libpldm/utils.h>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +05306
7#include <algorithm>
8#include <array>
Andrew Jeffery9c766792022-08-10 23:12:49 +09309#include <bitset>
Andrew Jeffery5a5129b2024-12-04 16:12:40 +103010#include <cstddef>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053011#include <cstdint>
Andrew Jeffery9c766792022-08-10 23:12:49 +093012#include <cstring>
Matt Johnstond5d1f662024-11-27 13:30:20 +080013#include <span>
Manojkiran Eda9a8e4972022-11-28 16:38:21 +053014#include <string>
15#include <string_view>
16#include <vector>
Andrew Jeffery9c766792022-08-10 23:12:49 +093017
Chris Wang4c1f2c72024-03-21 17:09:44 +080018#include "msgbuf.h"
19
Andrew Jefferydec237b2024-11-08 14:33:45 +103020#include <gmock/gmock.h>
Andrew Jeffery9c766792022-08-10 23:12:49 +093021#include <gtest/gtest.h>
22
Andrew Jefferydec237b2024-11-08 14:33:45 +103023using testing::ElementsAreArray;
24
Andrew Jeffery9c766792022-08-10 23:12:49 +093025constexpr auto hdrSize = sizeof(pldm_msg_hdr);
26
Matt Johnstoncf9a2df2024-11-07 15:29:29 +080027#ifdef LIBPLDM_API_TESTING
28
29static const uint8_t FIXED_INSTANCE_ID = 31;
30
31/* data is a pointer to pldm message response header */
32static void check_response(const void* data, uint8_t command)
33{
34 auto enc = static_cast<const pldm_msg*>(data);
35 EXPECT_EQ(enc->hdr.request, PLDM_RESPONSE);
36 EXPECT_EQ(enc->hdr.type, PLDM_FWUP);
37 EXPECT_EQ(enc->hdr.command, command);
38 EXPECT_EQ(enc->hdr.reserved, 0);
39 EXPECT_EQ(enc->hdr.datagram, 0);
40 EXPECT_EQ(enc->hdr.header_ver, 0);
41 EXPECT_EQ(enc->hdr.instance_id, FIXED_INSTANCE_ID);
42}
43#endif
44
Andrew Jefferye038b962025-03-06 16:04:59 +103045static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
46 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0{0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d,
47 0x49, 0x43, 0x98, 0x00, 0xa0, 0x2f,
48 0x05, 0x9a, 0xca, 0x02};
49
50static constexpr uint8_t PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0 = 0x01;
Andrew Jeffery2613c272025-03-12 14:15:41 +103051
52static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
53 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1{
54 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
55 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a,
56 };
57
Carter Chenf72cf6f2025-06-24 15:34:49 +080058static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
59 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2{0x31, 0x19, 0xce, 0x2f, 0xe8, 0x0a,
60 0x4a, 0x99, 0xaf, 0x6d, 0x46, 0xf8,
61 0xb1, 0x21, 0xf6, 0xbf};
62
Carter Chen01782742025-06-25 13:53:50 +080063static constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH>
64 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3{0x7b, 0x29, 0x1c, 0x99, 0x6d, 0xb6,
65 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
66 0x6E, 0x46, 0x3C, 0x78};
67
Andrew Jeffery150b06c2025-03-12 14:17:42 +103068static constexpr size_t PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 = 43;
69
70static constexpr std::array<uint8_t, PLDM_TIMESTAMP104_SIZE>
71 testPackageReleaseDateTime{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
Andrew Jefferye038b962025-03-06 16:04:59 +103073
Andrew Jeffery9c766792022-08-10 23:12:49 +093074TEST(DecodePackageHeaderInfo, goodPath)
75{
Andrew Jeffery9c766792022-08-10 23:12:49 +093076 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +093077 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +103078 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +103079 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +093080
Andrew Jefferya3eba612025-03-06 17:11:20 +103081 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +103082 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
83 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
85 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
86 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x61, 0xe3, 0x64, 0x6e};
Andrew Jeffery9c766792022-08-10 23:12:49 +093087 pldm_package_header_information pkgHeader{};
88 variable_field packageVersion{};
89
90 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
91 packagerHeaderInfo.size(),
92 &pkgHeader, &packageVersion);
93
Andrew Jeffery150b06c2025-03-12 14:17:42 +103094 ASSERT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093095 EXPECT_EQ(true,
96 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
Andrew Jefferye038b962025-03-06 16:04:59 +103097 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.begin(),
98 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.end()));
99 EXPECT_EQ(pkgHeader.package_header_format_version,
100 PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0);
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030101 EXPECT_EQ(pkgHeader.package_header_size, packageHeaderSize);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930102 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
103 pkgHeader.package_release_date_time +
104 PLDM_TIMESTAMP104_SIZE,
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030105 testPackageReleaseDateTime.begin(),
106 testPackageReleaseDateTime.end()));
Andrew Jeffery9c766792022-08-10 23:12:49 +0930107 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
108 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
109 EXPECT_EQ(pkgHeader.package_version_string_length,
110 packageVersionStr.size());
111 std::string packageVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930112 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930113 reinterpret_cast<const char*>(packageVersion.ptr),
114 packageVersion.length);
115 EXPECT_EQ(packageVersionString, packageVersionStr);
116}
117
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030118TEST(DecodePackageHeaderInfo, invalidArguments)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930119{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930120 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +1030121 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030122 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930123
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030124 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030125 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
126 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
128 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
129 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030130
131 pldm_package_header_information packageHeader{};
132 variable_field packageVersion{};
133 int rc = 0;
134
135 rc = decode_pldm_package_header_info(nullptr, packagerHeaderInfo.size(),
136 &packageHeader, &packageVersion);
137 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
138
139 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
140 packagerHeaderInfo.size(), nullptr,
141 &packageVersion);
142 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
143
144 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
145 packagerHeaderInfo.size(),
146 &packageHeader, nullptr);
147 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
148}
149
150TEST(DecodePackageHeaderInfo, invalidPackageLengths)
151{
152 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
153 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030154 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030155
156 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030157 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
158 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
160 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
161 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030162
163 pldm_package_header_information packageHeader{};
164 variable_field packageVersion{};
165 int rc = 0;
166
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030167 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 0,
168 &packageHeader, &packageVersion);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030169 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030170
171 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 35,
172 &packageHeader, &packageVersion);
173 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
174
175 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 36,
176 &packageHeader, &packageVersion);
177 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
178
179 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
180 packagerHeaderInfo.size() - 1,
181 &packageHeader, &packageVersion);
182 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
183}
184
185TEST(DecodePackageHeaderInfo, unspecifiedPackageHeaderIdentifier)
186{
187 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
188 constexpr size_t packageHeaderSize =
189 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
190
191 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
192 0xff, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
193 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
195 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
196 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
197
198 pldm_package_header_information packageHeader{};
199 variable_field packageVersion{};
200 int rc = 0;
201
202 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
203 packagerHeaderInfo.size(),
204 &packageHeader, &packageVersion);
205 EXPECT_EQ(rc, PLDM_ERROR);
206}
207
208TEST(DecodePackageHeaderInfo, incongruentPackageHeaderFormatRevision)
209{
210 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
211 constexpr size_t packageHeaderSize =
212 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + 1 + packageVersionStr.size();
213
214 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
215 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
216 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x37, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
218 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
219 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
220
221 pldm_package_header_information packageHeader{};
222 variable_field packageVersion{};
223 int rc = 0;
224
225 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
226 packagerHeaderInfo.size(),
227 &packageHeader, &packageVersion);
Andrew Jeffery2613c272025-03-12 14:15:41 +1030228 EXPECT_EQ(rc, PLDM_ERROR);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030229}
230
231TEST(DecodePackageHeaderInfo, invalidPackageVersionStringType)
232{
233 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
234 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030235 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030236
237 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030238 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
239 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
241 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
242 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930243
244 pldm_package_header_information packageHeader{};
245 variable_field packageVersion{};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030246 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930247
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030248 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
249 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930250 &packageHeader, &packageVersion);
251 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030252}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930253
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030254TEST(DecodePackageHeaderInfo, invalidPackageVersionStringLength)
255{
256 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
257 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030258 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930259
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030260 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030261 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
262 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
264 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
265 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030266
267 pldm_package_header_information packageHeader{};
268 variable_field packageVersion{};
269 int rc = 0;
270
271 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
272 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930273 &packageHeader, &packageVersion);
274 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030275}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930276
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030277TEST(DecodePackageHeaderInfo, corruptPackageVersionStringLength)
278{
279 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
280 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030281 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030282
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030283 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
284 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
285 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
287 0x00, 0x01, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
288 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030289
290 pldm_package_header_information packageHeader{};
291 variable_field packageVersion{};
292 int rc = 0;
293
294 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
295 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930296 &packageHeader, &packageVersion);
297 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030298}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930299
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030300TEST(DecodePackageHeaderInfo, invalidComponentBitmapBitLength)
301{
302 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
303 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030304 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030305
306 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030307 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
308 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x07,
310 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
311 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
312
313 pldm_package_header_information packageHeader{};
314 variable_field packageVersion{};
315 int rc = 0;
316
317 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
318 invalidPackagerHeaderInfo.size(),
319 &packageHeader, &packageVersion);
320 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
321}
322
323TEST(DecodePackageHeaderInfo, badChecksum)
324{
325 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
326 constexpr size_t packageHeaderSize =
327 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
328
329 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
330 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
331 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x10,
333 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
334 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030335
336 pldm_package_header_information packageHeader{};
337 variable_field packageVersion{};
338 int rc = 0;
339
340 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
341 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930342 &packageHeader, &packageVersion);
343 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
344}
345
346TEST(DecodeFirmwareDeviceIdRecord, goodPath)
347{
348 constexpr uint8_t descriptorCount = 1;
349 // Continue component updates after failure
350 constexpr std::bitset<32> deviceUpdateFlag{1};
351 constexpr uint16_t componentBitmapBitLength = 16;
352 // Applicable Components - 1,2,5,8,9
353 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
354 // ComponentImageSetVersionString
355 constexpr std::string_view imageSetVersionStr{"VersionString1"};
356 // Initial descriptor - UUID
357 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
358 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
359 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
360 constexpr uint16_t fwDevicePkgDataLen = 2;
361 // FirmwareDevicePackageData
362 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
363 0xcd};
364 // Size of the firmware device ID record
365 constexpr uint16_t recordLen =
366 sizeof(pldm_firmware_device_id_record) +
367 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
368 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
369 uuid.size() + fwDevicePkgData.size();
370 // Firmware device ID record
371 constexpr std::array<uint8_t, recordLen> record{
372 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
373 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
374 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
375 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
376 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
377
378 pldm_firmware_device_id_record deviceIdRecHeader{};
379 variable_field applicableComponents{};
380 variable_field outCompImageSetVersionStr{};
381 variable_field recordDescriptors{};
382 variable_field outFwDevicePkgData{};
383
384 auto rc = decode_firmware_device_id_record(
385 record.data(), record.size(), componentBitmapBitLength,
386 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
387 &recordDescriptors, &outFwDevicePkgData);
388
Andrew Jefferybacbbac2025-03-12 04:02:18 +0000389 ASSERT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930390 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
391 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
392 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
393 deviceUpdateFlag);
394 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
395 PLDM_STR_TYPE_ASCII);
396 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
397 imageSetVersionStr.size());
398 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
399
400 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
401 EXPECT_EQ(true,
402 std::equal(applicableComponents.ptr,
403 applicableComponents.ptr + applicableComponents.length,
404 applicableComponentsBitfield.begin(),
405 applicableComponentsBitfield.end()));
406
407 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
408 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930409 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930410 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
411 outCompImageSetVersionStr.length);
412 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
413
414 uint16_t descriptorType = 0;
415 uint16_t descriptorLen = 0;
416 variable_field descriptorData{};
417 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
418 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
419 recordDescriptors.length,
420 &descriptorType, &descriptorData);
421 EXPECT_EQ(rc, PLDM_SUCCESS);
422 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
423 sizeof(descriptorLen) +
424 descriptorData.length);
425 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
426 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
427 EXPECT_EQ(true, std::equal(descriptorData.ptr,
428 descriptorData.ptr + descriptorData.length,
429 uuid.begin(), uuid.end()));
430
431 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
432 EXPECT_EQ(true,
433 std::equal(outFwDevicePkgData.ptr,
434 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
435 fwDevicePkgData.begin(), fwDevicePkgData.end()));
436}
437
438TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
439{
440 constexpr uint8_t descriptorCount = 1;
441 // Continue component updates after failure
442 constexpr std::bitset<32> deviceUpdateFlag{1};
443 constexpr uint16_t componentBitmapBitLength = 8;
444 // Applicable Components - 1,2
445 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
446 // ComponentImageSetVersionString
447 constexpr std::string_view imageSetVersionStr{"VersionString1"};
448 // Initial descriptor - UUID
449 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
450 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
451 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
452 constexpr uint16_t fwDevicePkgDataLen = 0;
453
454 // Size of the firmware device ID record
455 constexpr uint16_t recordLen =
456 sizeof(pldm_firmware_device_id_record) +
457 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
458 imageSetVersionStr.size() +
459 sizeof(pldm_descriptor_tlv().descriptor_type) +
460 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
461 fwDevicePkgDataLen;
462 // Firmware device ID record
463 constexpr std::array<uint8_t, recordLen> record{
464 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
465 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
466 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
467 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
468
469 pldm_firmware_device_id_record deviceIdRecHeader{};
470 variable_field applicableComponents{};
471 variable_field outCompImageSetVersionStr{};
472 variable_field recordDescriptors{};
473 variable_field outFwDevicePkgData{};
474
475 auto rc = decode_firmware_device_id_record(
476 record.data(), record.size(), componentBitmapBitLength,
477 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
478 &recordDescriptors, &outFwDevicePkgData);
479
480 EXPECT_EQ(rc, PLDM_SUCCESS);
481 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
482 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
483 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
484 deviceUpdateFlag);
485 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
486 PLDM_STR_TYPE_ASCII);
487 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
488 imageSetVersionStr.size());
489 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
490
491 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
492 EXPECT_EQ(true,
493 std::equal(applicableComponents.ptr,
494 applicableComponents.ptr + applicableComponents.length,
495 applicableComponentsBitfield.begin(),
496 applicableComponentsBitfield.end()));
497
498 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
499 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930500 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930501 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
502 outCompImageSetVersionStr.length);
503 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
504
505 uint16_t descriptorType = 0;
506 uint16_t descriptorLen = 0;
507 variable_field descriptorData{};
508 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
509 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
510 recordDescriptors.length,
511 &descriptorType, &descriptorData);
512 EXPECT_EQ(rc, PLDM_SUCCESS);
513 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
514 sizeof(descriptorLen) +
515 descriptorData.length);
516 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
517 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
518 EXPECT_EQ(true, std::equal(descriptorData.ptr,
519 descriptorData.ptr + descriptorData.length,
520 uuid.begin(), uuid.end()));
521
522 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
523 EXPECT_EQ(outFwDevicePkgData.length, 0);
524}
525
526TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
527{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930528 // Invalid ComponentImageSetVersionStringType
Andrew Jeffery92c32362025-03-10 03:36:46 +0000529 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
530 0x00, 0x06, 0x0e, 0x00, 0x00};
531 constexpr uint16_t componentBitmapBitLength = 8;
532
533 pldm_firmware_device_id_record deviceIdRecHeader{};
534 variable_field outCompImageSetVersionStr{};
535 variable_field applicableComponents{};
536 variable_field outFwDevicePkgData{};
537 variable_field recordDescriptors{};
538 int rc = 0;
539
540 rc = decode_firmware_device_id_record(
541 nullptr, rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
542 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
543 &outFwDevicePkgData);
544 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
545
546 rc = decode_firmware_device_id_record(
547 rec.data(), rec.size(), componentBitmapBitLength, nullptr,
548 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
549 &outFwDevicePkgData);
550 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
551
552 rc = decode_firmware_device_id_record(
553 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
554 nullptr, &outCompImageSetVersionStr, &recordDescriptors,
555 &outFwDevicePkgData);
556 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
557
558 rc = decode_firmware_device_id_record(
559 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
560 &applicableComponents, nullptr, &recordDescriptors,
561 &outFwDevicePkgData);
562 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
563
564 rc = decode_firmware_device_id_record(
565 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
566 &applicableComponents, &outCompImageSetVersionStr, nullptr,
567 &outFwDevicePkgData);
568 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
569
570 rc = decode_firmware_device_id_record(
571 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
572 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
573 nullptr);
574 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
575
576 rc = decode_firmware_device_id_record(
577 rec.data(), rec.size() - 1, componentBitmapBitLength,
578 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
579 &recordDescriptors, &outFwDevicePkgData);
580 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
581
582 rc = decode_firmware_device_id_record(
583 rec.data(), rec.size(), componentBitmapBitLength + 1,
584 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
585 &recordDescriptors, &outFwDevicePkgData);
586 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
587
588 rc = decode_firmware_device_id_record(
589 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
590 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
591 &outFwDevicePkgData);
592 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
593}
594
595TEST(DecodeFirmwareDeviceIdRecord, invalidComponentImageSetVersionStringLength)
596{
597 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
598 0x00, 0x01, 0x00, 0x00, 0x00};
599 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930600
601 int rc = 0;
602 pldm_firmware_device_id_record deviceIdRecHeader{};
603 variable_field applicableComponents{};
604 variable_field outCompImageSetVersionStr{};
605 variable_field recordDescriptors{};
606 variable_field outFwDevicePkgData{};
607
608 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000609 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
610 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930611 &outFwDevicePkgData);
612 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000613}
614
615TEST(DecodeFirmwareDeviceIdRecord, shortBuffer)
616{
617 constexpr std::array<uint8_t, 11> rec{0x2e, 0x00, 0x01, 0x01, 0x00, 0x00,
618 0x00, 0x01, 0x0e, 0x00, 0x00};
619 constexpr uint16_t componentBitmapBitLength = 8;
620
621 pldm_firmware_device_id_record deviceIdRecHeader{};
622 variable_field outCompImageSetVersionStr{};
623 variable_field applicableComponents{};
624 variable_field outFwDevicePkgData{};
625 variable_field recordDescriptors{};
626 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930627
628 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000629 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
630 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
631 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930632 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000633}
634
635TEST(DecodeFirmwareDeviceIdRecord, recordLengthMismatch)
636{
637 constexpr std::array<uint8_t, 11> rec{0x15, 0x00, 0x01, 0x01, 0x00, 0x00,
638 0x00, 0x01, 0x0e, 0x02, 0x00};
639 constexpr uint16_t componentBitmapBitLength = 8;
640
641 pldm_firmware_device_id_record deviceIdRecHeader{};
642 variable_field outCompImageSetVersionStr{};
643 variable_field applicableComponents{};
644 variable_field outFwDevicePkgData{};
645 variable_field recordDescriptors{};
646 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930647
648 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000649 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
650 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
651 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930652 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000653}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930654
Andrew Jeffery92c32362025-03-10 03:36:46 +0000655TEST(DecodeFirmwareDeviceIdRecord, invalidFirmwareDevicePackageDataLength)
656{
657 constexpr std::array<uint8_t, 49> rec{
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800658 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
659 // FirmwareDevicePackageDataLength = 0xffff
660 0xff, 0xff,
661 //
662 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
663 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
664 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
665 0xab, 0xcd};
Andrew Jeffery92c32362025-03-10 03:36:46 +0000666 constexpr uint16_t componentBitmapBitLength = 8;
667
668 pldm_firmware_device_id_record deviceIdRecHeader{};
669 variable_field outCompImageSetVersionStr{};
670 variable_field applicableComponents{};
671 variable_field outFwDevicePkgData{};
672 variable_field recordDescriptors{};
673 int rc = 0;
674
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800675 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000676 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
677 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
678 &outFwDevicePkgData);
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800679 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930680}
681
682TEST(DecodeDescriptors, goodPath3Descriptors)
683{
684 // In the descriptor data there are 3 descriptor entries
685 // 1) IANA enterprise ID
686 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
687 0x0a, 0x0b, 0x0c, 0xd};
688 // 2) UUID
689 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
690 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
691 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
692 // 3) Vendor Defined
693 constexpr std::string_view vendorTitle{"OpenBMC"};
694 constexpr size_t vendorDescriptorLen = 2;
695 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
696 0x01, 0x02};
697
698 constexpr size_t vendorDefinedDescriptorLen =
699 sizeof(pldm_vendor_defined_descriptor_title_data()
700 .vendor_defined_descriptor_title_str_type) +
701 sizeof(pldm_vendor_defined_descriptor_title_data()
702 .vendor_defined_descriptor_title_str_len) +
703 vendorTitle.size() + vendorDescriptorData.size();
704
705 constexpr size_t descriptorsLength =
706 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
707 sizeof(pldm_descriptor_tlv().descriptor_length)) +
708 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
709
710 constexpr std::array<uint8_t, descriptorsLength> descriptors{
711 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
712 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600713 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930714 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
715
716 size_t descriptorCount = 1;
717 size_t descriptorsRemainingLength = descriptorsLength;
718 int rc = 0;
719
720 while (descriptorsRemainingLength && (descriptorCount <= 3))
721 {
722 uint16_t descriptorType = 0;
723 uint16_t descriptorLen = 0;
724 variable_field descriptorData{};
725
726 rc = decode_descriptor_type_length_value(
727 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
728 descriptorsRemainingLength, &descriptorType, &descriptorData);
729 EXPECT_EQ(rc, PLDM_SUCCESS);
730
731 if (descriptorCount == 1)
732 {
733 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
734 EXPECT_EQ(descriptorData.length,
735 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
736 EXPECT_EQ(true,
737 std::equal(descriptorData.ptr,
738 descriptorData.ptr + descriptorData.length,
739 iana.begin(), iana.end()));
740 }
741 else if (descriptorCount == 2)
742 {
743 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
744 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
745 EXPECT_EQ(true,
746 std::equal(descriptorData.ptr,
747 descriptorData.ptr + descriptorData.length,
748 uuid.begin(), uuid.end()));
749 }
750 else if (descriptorCount == 3)
751 {
752 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
753 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
754
755 uint8_t descriptorTitleStrType = 0;
756 variable_field descriptorTitleStr{};
757 variable_field vendorDefinedDescriptorData{};
758
759 rc = decode_vendor_defined_descriptor_value(
760 descriptorData.ptr, descriptorData.length,
761 &descriptorTitleStrType, &descriptorTitleStr,
762 &vendorDefinedDescriptorData);
763 EXPECT_EQ(rc, PLDM_SUCCESS);
764
765 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
766 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
767 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930768 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930769 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
770 descriptorTitleStr.length);
771 EXPECT_EQ(vendorTitleStr, vendorTitle);
772
773 EXPECT_EQ(vendorDefinedDescriptorData.length,
774 vendorDescriptorData.size());
775 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
776 vendorDefinedDescriptorData.ptr +
777 vendorDefinedDescriptorData.length,
778 vendorDescriptorData.begin(),
779 vendorDescriptorData.end()));
780 }
781
782 descriptorsRemainingLength -= sizeof(descriptorType) +
783 sizeof(descriptorLen) +
784 descriptorData.length;
785 descriptorCount++;
786 }
787}
788
789TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
790{
791 int rc = 0;
792 // IANA Enterprise ID descriptor length incorrect
793 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
794 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
795 uint16_t descriptorType = 0;
796 variable_field descriptorData{};
797
798 rc = decode_descriptor_type_length_value(nullptr,
799 invalidIANADescriptor1.size(),
800 &descriptorType, &descriptorData);
801 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
802
803 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
804 invalidIANADescriptor1.size(),
805 nullptr, &descriptorData);
806 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
807
808 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
809 invalidIANADescriptor1.size(),
810 &descriptorType, nullptr);
811 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
812
813 rc = decode_descriptor_type_length_value(
814 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
815 &descriptorType, &descriptorData);
816 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
817
818 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
819 invalidIANADescriptor1.size(),
820 &descriptorType, &descriptorData);
Andrew Jeffery779e9db2025-02-21 12:14:28 +1030821 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930822
823 // IANA Enterprise ID descriptor data less than length
824 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
825 0x0a, 0x0b, 0x0c};
826 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
827 invalidIANADescriptor2.size(),
828 &descriptorType, &descriptorData);
829 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
830}
831
832TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
833{
834 int rc = 0;
835 // VendorDefinedDescriptorTitleStringType is invalid
836 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
837 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
838 uint8_t descriptorStringType = 0;
839 variable_field descriptorTitleStr{};
840 variable_field vendorDefinedDescriptorData{};
841
842 rc = decode_vendor_defined_descriptor_value(
843 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
844 &descriptorTitleStr, &vendorDefinedDescriptorData);
845 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
846
847 rc = decode_vendor_defined_descriptor_value(
848 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
849 &descriptorStringType, &descriptorTitleStr,
850 &vendorDefinedDescriptorData);
851 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
852
853 rc = decode_vendor_defined_descriptor_value(
854 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
855 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
856 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
857
858 rc = decode_vendor_defined_descriptor_value(
859 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
860 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
861 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
862
863 rc = decode_vendor_defined_descriptor_value(
864 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
865 &descriptorStringType, &descriptorTitleStr, nullptr);
866 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
867
868 rc = decode_vendor_defined_descriptor_value(
869 invalidVendorDescriptor1.data(),
870 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
871 &descriptorStringType, &descriptorTitleStr,
872 &vendorDefinedDescriptorData);
873 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
874
875 rc = decode_vendor_defined_descriptor_value(
876 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
877 &descriptorStringType, &descriptorTitleStr,
878 &vendorDefinedDescriptorData);
879 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
880
881 // VendorDefinedDescriptorTitleStringLength is 0
882 std::array<uint8_t, 9> invalidVendorDescriptor2{
883 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
884 rc = decode_vendor_defined_descriptor_value(
885 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
886 &descriptorStringType, &descriptorTitleStr,
887 &vendorDefinedDescriptorData);
888 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
889
890 // VendorDefinedDescriptorData not present in the data
891 std::array<uint8_t, 9> invalidVendorDescriptor3{
892 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
893 rc = decode_vendor_defined_descriptor_value(
894 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
895 &descriptorStringType, &descriptorTitleStr,
896 &vendorDefinedDescriptorData);
897 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
898}
899
900TEST(DecodeComponentImageInfo, goodPath)
901{
902 // Firmware
903 constexpr uint16_t compClassification = 16;
904 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600905 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930906 // Force update
907 constexpr std::bitset<16> compOptions{1};
908 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
909 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
910 // Random ComponentLocationOffset
911 constexpr uint32_t compLocOffset = 357;
912 // Random ComponentSize
913 constexpr uint32_t compSize = 27;
914 // ComponentVersionString
915 constexpr std::string_view compVersionStr{"VersionString1"};
916 constexpr size_t compImageInfoSize =
917 sizeof(pldm_component_image_information) + compVersionStr.size();
918
919 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
920 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
921 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
922 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
923 pldm_component_image_information outCompImageInfo{};
924 variable_field outCompVersionStr{};
925
926 auto rc =
927 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
928 &outCompImageInfo, &outCompVersionStr);
929
930 EXPECT_EQ(rc, PLDM_SUCCESS);
931 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
932 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
933 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
934 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
935 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
936 reqCompActivationMethod);
937 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
938 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
939 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
940 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
941 compVersionStr.size());
942
943 EXPECT_EQ(outCompVersionStr.length,
944 outCompImageInfo.comp_version_string_length);
945 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930946 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930947 reinterpret_cast<const char*>(outCompVersionStr.ptr),
948 outCompVersionStr.length);
949 EXPECT_EQ(componentVersionString, compVersionStr);
950}
951
952TEST(DecodeComponentImageInfo, errorPaths)
953{
954 int rc = 0;
955 // ComponentVersionString
956 constexpr std::string_view compVersionStr{"VersionString1"};
957 constexpr size_t compImageInfoSize =
958 sizeof(pldm_component_image_information) + compVersionStr.size();
959 // Invalid ComponentVersionStringType - 0x06
960 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
961 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
962 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
963 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
964 pldm_component_image_information outCompImageInfo{};
965 variable_field outCompVersionStr{};
966
967 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
968 &outCompImageInfo, &outCompVersionStr);
969 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
970
971 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
972 invalidCompImageInfo1.size(), nullptr,
973 &outCompVersionStr);
974 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
975
976 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
977 invalidCompImageInfo1.size(),
978 &outCompImageInfo, nullptr);
979 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
980
981 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
982 sizeof(pldm_component_image_information) -
983 1,
984 &outCompImageInfo, &outCompVersionStr);
985 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
986
987 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
988 invalidCompImageInfo1.size(),
989 &outCompImageInfo, &outCompVersionStr);
990 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
991
992 // Invalid ComponentVersionStringLength - 0x00
993 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
994 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
995 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
996 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
997 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
998 invalidCompImageInfo2.size(),
999 &outCompImageInfo, &outCompVersionStr);
1000 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1001
1002 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001003 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +09301004 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
1005 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
1006 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1007 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1008
1009 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
1010 invalidCompImageInfo3.size() - 1,
1011 &outCompImageInfo, &outCompVersionStr);
1012 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1013
1014 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
1015 invalidCompImageInfo3.size(),
1016 &outCompImageInfo, &outCompVersionStr);
1017 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1018
1019 // Invalid ComponentLocationOffset - 0
1020 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
1021 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1022 0x00, 0x00, 0x00, 0x00, 0x1b, 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(invalidCompImageInfo4.data(),
1025 invalidCompImageInfo4.size(),
1026 &outCompImageInfo, &outCompVersionStr);
1027 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1028
1029 // Invalid ComponentSize - 0
1030 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
1031 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1032 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1033 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1034 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
1035 invalidCompImageInfo5.size(),
1036 &outCompImageInfo, &outCompVersionStr);
1037 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1038}
1039
1040TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
1041{
1042 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301043 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301044 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1045
1046 uint8_t instanceId = 0x01;
1047
1048 auto rc = encode_query_device_identifiers_req(
1049 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
1050 EXPECT_EQ(rc, PLDM_SUCCESS);
1051 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1052 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1053 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1054 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
1055}
1056
1057TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
1058{
1059 // descriptorDataLen is not fixed here taking it as 6
1060 constexpr uint8_t descriptorDataLen = 6;
1061 std::array<uint8_t, hdrSize +
1062 sizeof(struct pldm_query_device_identifiers_resp) +
1063 descriptorDataLen>
1064 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301065 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301066 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
1067 responseMsg.data() + hdrSize);
1068
1069 inResp->completion_code = PLDM_SUCCESS;
1070 inResp->device_identifiers_len = htole32(descriptorDataLen);
1071 inResp->descriptor_count = 1;
1072
1073 // filling descriptor data
1074 std::fill_n(responseMsg.data() + hdrSize +
1075 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001076 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301077
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301078 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301079 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1080 uint8_t completionCode = PLDM_SUCCESS;
1081 uint32_t deviceIdentifiersLen = 0;
1082 uint8_t descriptorCount = 0;
1083 uint8_t* outDescriptorData = nullptr;
1084
1085 auto rc = decode_query_device_identifiers_resp(
1086 response, responseMsg.size() - hdrSize, &completionCode,
1087 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
1088
1089 EXPECT_EQ(rc, PLDM_SUCCESS);
1090 EXPECT_EQ(completionCode, PLDM_SUCCESS);
1091 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
1092 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
1093 EXPECT_EQ(true,
1094 std::equal(outDescriptorData,
1095 outDescriptorData + deviceIdentifiersLen,
1096 responseMsg.begin() + hdrSize +
1097 sizeof(struct pldm_query_device_identifiers_resp),
1098 responseMsg.end()));
1099}
1100
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001101#ifdef LIBPLDM_API_TESTING
1102TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
1103{
1104 int rc;
1105 PLDM_MSG_DEFINE_P(enc, 1000);
1106 size_t enc_payload_len = 1000;
1107 pldm_descriptor check_desc[] = {
1108 {
1109 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
1110 .descriptor_length = 4,
1111 .descriptor_data = "a123",
1112 },
1113 {
1114 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
1115 .descriptor_length = 3,
1116 .descriptor_data = "987",
1117 },
1118 };
1119 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
1120 enc, &enc_payload_len);
1121 EXPECT_EQ(rc, 0);
1122 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
1123 ElementsAreArray<uint8_t>({
1124 // completion code
1125 0x00,
1126 // device identifiers length = 15
1127 0x0f,
1128 0x00,
1129 0x00,
1130 0x00,
1131 // descriptor count
1132 0x02,
1133 // desc 0
1134 0x01,
1135 0x00,
1136 0x04,
1137 0x00,
1138 0x61,
1139 0x31,
1140 0x32,
1141 0x33,
1142 // desc 1
1143 0xff,
1144 0xff,
1145 0x03,
1146 0x00,
1147 0x39,
1148 0x38,
1149 0x37,
1150 }));
1151
1152 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
1153}
1154#endif
1155
Andrew Jeffery9c766792022-08-10 23:12:49 +09301156TEST(GetFirmwareParameters, goodPathEncodeRequest)
1157{
1158 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301159 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301160 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1161 uint8_t instanceId = 0x01;
1162
1163 auto rc = encode_get_firmware_parameters_req(
1164 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
1165 EXPECT_EQ(rc, PLDM_SUCCESS);
1166 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1167 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1168 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1169 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
1170}
1171
1172TEST(GetFirmwareParameters, decodeResponse)
1173{
1174 // CapabilitiesDuringUpdate of the firmware device
1175 // Firmware device downgrade restrictions [Bit position 8] &
1176 // Firmware Device Partial Updates [Bit position 3]
1177 constexpr std::bitset<32> fdCapabilities{0x00000104};
1178 constexpr uint16_t compCount = 1;
1179 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1180 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1181
1182 // constexpr uint16_t compClassification = 16;
1183 // constexpr uint16_t compIdentifier = 300;
1184 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001185 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301186 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
1187 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1188 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
1189 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
1190 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
1191 constexpr std::string_view activeCompVersion{"VersionString3"};
1192 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +09301193
1194 constexpr size_t compParamTableSize =
1195 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
1196 pendingCompVersion.size();
1197
1198 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001199 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301200 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1201 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
1202 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
1203 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1204 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1205
1206 constexpr size_t getFwParamsPayloadLen =
1207 sizeof(pldm_get_firmware_parameters_resp) +
1208 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1209 compParamTableSize;
1210
1211 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1212 getFwParamsResponse{
1213 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1214 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1215 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1216 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001217 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301218 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1219 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1220 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1221 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1222 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1223
1224 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301225 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301226 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1227 pldm_get_firmware_parameters_resp outResp{};
1228 variable_field outActiveCompImageSetVersion{};
1229 variable_field outPendingCompImageSetVersion{};
1230 variable_field outCompParameterTable{};
1231
1232 auto rc = decode_get_firmware_parameters_resp(
1233 responseMsg, getFwParamsPayloadLen, &outResp,
1234 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1235 &outCompParameterTable);
1236
1237 EXPECT_EQ(rc, PLDM_SUCCESS);
1238 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1239 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1240 EXPECT_EQ(outResp.comp_count, compCount);
1241 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1242 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1243 activeCompImageSetVersion.size());
1244 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1245 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1246 pendingCompImageSetVersion.size());
1247 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301248 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301249 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1250 outActiveCompImageSetVersion.length);
1251 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1252 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301253 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301254 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1255 outPendingCompImageSetVersion.length);
1256 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1257 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1258 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1259 outCompParameterTable.ptr +
1260 outCompParameterTable.length,
1261 compParamTable.begin(), compParamTable.end()));
1262}
1263
1264TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1265{
1266 // CapabilitiesDuringUpdate of the firmware device
1267 // FD Host Functionality during Firmware Update [Bit position 2] &
1268 // Component Update Failure Retry Capability [Bit position 1]
1269 constexpr std::bitset<32> fdCapabilities{0x06};
1270 constexpr uint16_t compCount = 0;
1271 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1272 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1273
1274 constexpr size_t getFwParamsPayloadLen =
1275 sizeof(pldm_get_firmware_parameters_resp) +
1276 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1277
1278 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1279 getFwParamsResponse{
1280 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1281 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1282 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1283 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1284
1285 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301286 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301287 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1288 pldm_get_firmware_parameters_resp outResp{};
1289 variable_field outActiveCompImageSetVersion{};
1290 variable_field outPendingCompImageSetVersion{};
1291 variable_field outCompParameterTable{};
1292
1293 auto rc = decode_get_firmware_parameters_resp(
1294 responseMsg, getFwParamsPayloadLen, &outResp,
1295 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1296 &outCompParameterTable);
1297
1298 EXPECT_EQ(rc, PLDM_SUCCESS);
1299 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1300 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1301 EXPECT_EQ(outResp.comp_count, compCount);
1302 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1303 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1304 activeCompImageSetVersion.size());
1305 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1306 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1307 pendingCompImageSetVersion.size());
1308 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301309 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301310 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1311 outActiveCompImageSetVersion.length);
1312 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1313 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301314 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301315 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1316 outPendingCompImageSetVersion.length);
1317 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1318 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1319 EXPECT_EQ(outCompParameterTable.length, 0);
1320}
1321
1322TEST(GetFirmwareParameters,
1323 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1324{
1325 // CapabilitiesDuringUpdate of the firmware device
1326 // FD Host Functionality during Firmware Update [Bit position 2] &
1327 // Component Update Failure Retry Capability [Bit position 1]
1328 constexpr std::bitset<32> fdCapabilities{0x06};
1329 constexpr uint16_t compCount = 0;
1330 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1331
1332 constexpr size_t getFwParamsPayloadLen =
1333 sizeof(pldm_get_firmware_parameters_resp) +
1334 activeCompImageSetVersion.size();
1335
1336 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1337 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1338 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1339 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1340 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1341
1342 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301343 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301344 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1345 pldm_get_firmware_parameters_resp outResp{};
1346 variable_field outActiveCompImageSetVersion{};
1347 variable_field outPendingCompImageSetVersion{};
1348 variable_field outCompParameterTable{};
1349
1350 auto rc = decode_get_firmware_parameters_resp(
1351 responseMsg, getFwParamsPayloadLen, &outResp,
1352 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1353 &outCompParameterTable);
1354
1355 EXPECT_EQ(rc, PLDM_SUCCESS);
1356 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1357 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1358 EXPECT_EQ(outResp.comp_count, compCount);
1359 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1360 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1361 activeCompImageSetVersion.size());
1362 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1363 PLDM_STR_TYPE_UNKNOWN);
1364 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1365 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301366 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301367 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1368 outActiveCompImageSetVersion.length);
1369 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1370 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1371 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1372 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1373 EXPECT_EQ(outCompParameterTable.length, 0);
1374}
1375
1376TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1377{
1378 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1379 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1380
1381 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301382 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301383 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1384 pldm_get_firmware_parameters_resp outResp{};
1385 variable_field outActiveCompImageSetVersion{};
1386 variable_field outPendingCompImageSetVersion{};
1387 variable_field outCompParameterTable{};
1388
1389 auto rc = decode_get_firmware_parameters_resp(
1390 responseMsg, getFwParamsResponse.size(), &outResp,
1391 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1392 &outCompParameterTable);
1393
1394 EXPECT_EQ(rc, PLDM_SUCCESS);
1395 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1396}
1397
1398TEST(GetFirmwareParameters, errorPathdecodeResponse)
1399{
1400 int rc = 0;
1401 // Invalid ActiveComponentImageSetVersionStringType
1402 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1404 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1405
1406 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301407 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301408 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1409 pldm_get_firmware_parameters_resp outResp{};
1410 variable_field outActiveCompImageSetVersion{};
1411 variable_field outPendingCompImageSetVersion{};
1412 variable_field outCompParameterTable{};
1413
1414 rc = decode_get_firmware_parameters_resp(
1415 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1416 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1417 &outCompParameterTable);
1418 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1419
1420 rc = decode_get_firmware_parameters_resp(
1421 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1422 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1423 &outCompParameterTable);
1424 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1425
1426 rc = decode_get_firmware_parameters_resp(
1427 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1428 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1429 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1430
1431 rc = decode_get_firmware_parameters_resp(
1432 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1433 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1434 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1435
1436 rc = decode_get_firmware_parameters_resp(
1437 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1438 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1439 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1440
1441 rc = decode_get_firmware_parameters_resp(
1442 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1443 &outPendingCompImageSetVersion, &outCompParameterTable);
1444 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1445
1446 rc = decode_get_firmware_parameters_resp(
1447 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1448 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1449 &outCompParameterTable);
1450 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1451
1452 rc = decode_get_firmware_parameters_resp(
1453 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1454 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1455 &outCompParameterTable);
1456 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1457
1458 // Invalid ActiveComponentImageSetVersionStringLength
1459 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1461 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1462 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301463 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301464 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1465 rc = decode_get_firmware_parameters_resp(
1466 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1467 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1468 &outCompParameterTable);
1469 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1470
1471 // Invalid PendingComponentImageSetVersionStringType &
1472 // PendingComponentImageSetVersionStringLength
1473 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1474 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1475 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1476 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301477 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301478 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1479 rc = decode_get_firmware_parameters_resp(
1480 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1481 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1482 &outCompParameterTable);
1483 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1484
1485 // Invalid PendingComponentImageSetVersionStringType &
1486 // PendingComponentImageSetVersionStringLength
1487 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1488 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1489 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1490 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301491 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301492 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1493 rc = decode_get_firmware_parameters_resp(
1494 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1495 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1496 &outCompParameterTable);
1497 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1498
1499 // Total payload length less than expected
1500 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1501 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1502 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1503 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301504 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301505 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1506 rc = decode_get_firmware_parameters_resp(
1507 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1508 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1509 &outCompParameterTable);
1510 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1511}
1512
1513TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1514{
1515 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001516 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301517 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001518 constexpr uint16_t compIdentifier = 0x0c0d;
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001519 constexpr uint16_t compClassificationIndex = 0xf;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301520 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001521 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301522 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001523 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301524 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001525 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301526
1527 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1528 constexpr uint8_t activeCompVerStrLen = 8;
1529 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1530 constexpr uint8_t pendingCompVerStrLen = 8;
1531 constexpr size_t entryLength =
1532 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1533 pendingCompVerStrLen;
1534 std::array<uint8_t, entryLength> entry{};
1535
1536 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301537 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301538 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1539
1540 inEntry->comp_classification = htole16(compClassification);
1541 inEntry->comp_identifier = htole16(compIdentifier);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001542 inEntry->comp_classification_index = compClassificationIndex;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301543 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1544 inEntry->active_comp_ver_str_type = 1;
1545 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1546 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001547 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301548 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1549 inEntry->pending_comp_ver_str_type = 1;
1550 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1551 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001552 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301553 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1554 inEntry->capabilities_during_update.value =
1555 htole32(capabilitiesDuringUpdate);
1556 constexpr auto activeCompVerStrPos =
1557 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001558 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301559 constexpr auto pendingCompVerStrPos =
1560 activeCompVerStrPos + activeCompVerStrLen;
1561 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001562 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301563
1564 struct pldm_component_parameter_entry outEntry;
1565 struct variable_field outActiveCompVerStr;
1566 struct variable_field outPendingCompVerStr;
1567
1568 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1569 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1570 &outPendingCompVerStr);
1571
1572 EXPECT_EQ(rc, PLDM_SUCCESS);
1573
1574 EXPECT_EQ(outEntry.comp_classification, compClassification);
1575 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1576 EXPECT_EQ(inEntry->comp_classification_index,
1577 outEntry.comp_classification_index);
1578 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1579 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1580 outEntry.active_comp_ver_str_type);
1581 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1582 outEntry.active_comp_ver_str_len);
1583 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1584 outEntry.active_comp_release_date,
1585 sizeof(inEntry->active_comp_release_date)));
1586 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1587 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1588 outEntry.pending_comp_ver_str_type);
1589 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1590 outEntry.pending_comp_ver_str_len);
1591 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1592 outEntry.pending_comp_release_date,
1593 sizeof(inEntry->pending_comp_release_date)));
1594 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1595 EXPECT_EQ(outEntry.capabilities_during_update.value,
1596 capabilitiesDuringUpdate);
1597
1598 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1599 entry.data() + activeCompVerStrPos,
1600 outActiveCompVerStr.length));
1601 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1602 entry.data() + pendingCompVerStrPos,
1603 outPendingCompVerStr.length));
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001604
1605#ifdef LIBPLDM_API_TESTING
1606 /* Check the roundtrip matches */
1607 std::vector<uint8_t> enc_data(1000);
1608 size_t enc_payload_len = enc_data.size();
1609 struct pldm_component_parameter_entry_full entryFull = {
1610 .comp_classification = compClassification,
1611 .comp_identifier = compIdentifier,
1612 .comp_classification_index = compClassificationIndex,
1613 .active_ver =
1614 {
1615 .comparison_stamp = 0x12345678,
1616 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1617 .str_len = activeCompVerStrLen,
1618 .str_data = {}},
1619 .date = {},
1620 },
1621 .pending_ver =
1622 {
1623 .comparison_stamp = 0x12345678,
1624 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1625 .str_len = pendingCompVerStrLen,
1626 .str_data = {}},
1627 .date = {},
1628 },
1629 .comp_activation_methods = inEntry->comp_activation_methods,
1630 .capabilities_during_update = inEntry->capabilities_during_update,
1631 };
1632 // Fill strings
1633 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1634 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1635 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1636 0xff);
1637 std::fill_n(entryFull.pending_ver.date,
1638 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1639
1640 rc = encode_get_firmware_parameters_resp_comp_entry(
1641 &entryFull, enc_data.data(), &enc_payload_len);
1642 EXPECT_EQ(rc, PLDM_SUCCESS);
1643 EXPECT_EQ(enc_payload_len, entryLength);
1644 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1645#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301646}
1647
Chris Wang4c1f2c72024-03-21 17:09:44 +08001648TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1649{
1650 constexpr uint8_t instanceId = 1;
1651 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301652 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001653 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1654
1655 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1656
Unive Tien71e935c2024-11-25 17:21:43 +08001657 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001658 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1659 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1660 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1661 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1662}
1663
1664TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1665{
1666 constexpr uint8_t instanceId = 1;
1667
1668 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1669
Unive Tien71e935c2024-11-25 17:21:43 +08001670 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001671}
1672
1673TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1674{
1675 uint8_t completion_code_resp = PLDM_SUCCESS;
1676 uint8_t downstream_device_update_supported_resp =
1677 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1678 uint16_t number_of_downstream_devices_resp = 1;
1679 uint16_t max_number_of_downstream_devices_resp = 1;
1680 /** Capabilities of updating downstream devices
1681 * FDP supports downstream devices dynamically attached [Bit position 0] &
1682 * FDP supports downstream devices dynamically removed [Bit position 1]
1683 */
1684 bitfield32_t capabilities_resp = {.value = 0x0002};
1685 int rc;
1686
1687 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1688 responseMsg{};
1689
Andrew Jefferya1896962025-03-03 21:41:25 +10301690 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301691 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1692 responseMsg.size() - hdrSize);
1693 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001694
1695 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1696 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1697 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1698 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1699 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301700 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001701
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301702 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001703 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1704 struct pldm_query_downstream_devices_resp resp_data;
1705
1706 rc = decode_query_downstream_devices_resp(
1707 response, responseMsg.size() - hdrSize, &resp_data);
1708
Unive Tien71e935c2024-11-25 17:21:43 +08001709 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001710 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1711 EXPECT_EQ(resp_data.downstream_device_update_supported,
1712 downstream_device_update_supported_resp);
1713 EXPECT_EQ(resp_data.number_of_downstream_devices,
1714 number_of_downstream_devices_resp);
1715 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1716 max_number_of_downstream_devices_resp);
1717 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1718}
1719
1720TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1721{
1722 uint8_t completion_code_resp = PLDM_SUCCESS;
1723 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1724 uint16_t number_of_downstream_devices_resp = 1;
1725 uint16_t max_number_of_downstream_devices_resp = 1;
1726 /** Capabilities of updating downstream devices
1727 * FDP supports downstream devices dynamically attached [Bit position 0] &
1728 * FDP supports downstream devices dynamically removed [Bit position 1]
1729 */
1730 bitfield32_t capabilities_resp = {.value = 0x0002};
1731 int rc;
1732
1733 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1734 responseMsg{};
1735
Andrew Jefferya1896962025-03-03 21:41:25 +10301736 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301737 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1738 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301739 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001740 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1741 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1742 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1743 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1744 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301745 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001746
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301747 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001748 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1749 struct pldm_query_downstream_devices_resp resp_data;
1750
1751 rc = decode_query_downstream_devices_resp(
1752 response, responseMsg.size() - hdrSize, &resp_data);
1753
Unive Tien71e935c2024-11-25 17:21:43 +08001754 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001755}
1756
1757TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1758{
1759 uint8_t completion_code_resp = PLDM_SUCCESS;
1760 uint8_t downstream_device_update_supported_resp =
1761 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1762 uint16_t number_of_downstream_devices_resp = 1;
1763 uint16_t max_number_of_downstream_devices_resp = 1;
1764 /** Capabilities of updating downstream devices
1765 * FDP supports downstream devices dynamically attached [Bit position 0] &
1766 * FDP supports downstream devices dynamically removed [Bit position 1]
1767 */
1768 bitfield32_t capabilities_resp = {.value = 0x0002};
1769 int rc;
1770
1771 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1772 2 /* Inject error length*/>
1773 responseMsg{};
1774
Andrew Jefferya1896962025-03-03 21:41:25 +10301775 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301776 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1777 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301778 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001779
1780 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1781 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1782 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1783 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1784 // Inject error value
1785 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301786 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001787
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301788 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001789 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1790 struct pldm_query_downstream_devices_resp resp_data;
1791
1792 rc = decode_query_downstream_devices_resp(
1793 response, responseMsg.size() - hdrSize, &resp_data);
1794
Unive Tien71e935c2024-11-25 17:21:43 +08001795 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001796}
1797
Chris Wang458475a2024-03-26 17:59:19 +08001798TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1799{
1800 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301801 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1802 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001803 constexpr pldm_query_downstream_identifiers_req params_req{
1804 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001805
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001806 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1807 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001808 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301809 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1810 ElementsAreArray<uint8_t>(
1811 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001812}
1813
1814TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1815{
1816 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001817 constexpr pldm_query_downstream_identifiers_req params_req{
1818 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1819 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1820 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001821 constexpr size_t payload_length =
1822 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1823 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301824 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001825 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1826
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001827 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1828 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001829 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001830
1831 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001832 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001833 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001834
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001835 rc = encode_query_downstream_identifiers_req(
1836 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001837 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001838}
1839
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301840TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001841{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301842 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1843 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1844 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1845 constexpr uint32_t downstream_devices_length_resp = 0;
1846 constexpr uint16_t number_of_downstream_devices_resp = 0;
1847
1848 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1849 struct pldm_query_downstream_identifiers_resp resp_data = {};
1850 struct pldm_downstream_device_iter devs;
Andrew Jefferya1896962025-03-03 21:41:25 +10301851 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301852 int rc = 0;
1853
1854 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1855 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1856 ASSERT_EQ(rc, 0);
1857
1858 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1859 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1860 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1861 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1862 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1863
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301864 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301865
1866 rc = decode_query_downstream_identifiers_resp(
1867 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1868 &devs);
1869
Unive Tien71e935c2024-11-25 17:21:43 +08001870 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301871 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1872 EXPECT_EQ(resp_data.next_data_transfer_handle,
1873 next_data_transfer_handle_resp);
1874 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1875 EXPECT_EQ(resp_data.downstream_devices_length,
1876 downstream_devices_length_resp);
1877 EXPECT_EQ(resp_data.number_of_downstream_devices,
1878 number_of_downstream_devices_resp);
1879}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301880
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301881TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1882{
1883 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1884 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1885 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1886 constexpr uint32_t downstream_devices_length_resp = 0;
1887 constexpr uint16_t number_of_downstream_devices_resp = 1;
1888
1889 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1890 struct pldm_query_downstream_identifiers_resp resp = {};
1891 struct pldm_downstream_device_iter devs;
1892 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301893 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301894 int rc = 0;
1895
1896 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1897 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1898 ASSERT_EQ(rc, 0);
1899
1900 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1901 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1902 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1903 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1904 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1905
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301906 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301907
1908 rc = decode_query_downstream_identifiers_resp(
1909 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001910 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301911
1912 foreach_pldm_downstream_device(devs, dev, rc)
1913 {
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10301914 FAIL();
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301915 }
1916 ASSERT_NE(rc, 0);
1917}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301918
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301919TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1920{
1921 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301922 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001923 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1924 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1925 const uint32_t downstream_devices_length_resp =
1926 htole32(downstreamDevicesLen);
1927 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301928 constexpr size_t payloadLen =
1929 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001930
Andrew Jefferydec237b2024-11-08 14:33:45 +10301931 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301932 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301933 struct pldm_downstream_device_iter devs;
1934 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301935 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301936 int rc = 0;
1937
1938 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1939 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001940
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301941 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001942 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1943 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1944 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1945 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1946
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301947 /* Downstream device */
1948 pldm_msgbuf_insert_uint16(buf, 1);
1949 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001950
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301951 /* Device descriptor */
1952 pldm_msgbuf_insert_uint16(buf, 1);
1953 pldm_msgbuf_insert_uint16(buf, 4);
1954 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001955
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301956 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301957
1958 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1959 &resp_data, &devs);
1960
Unive Tien71e935c2024-11-25 17:21:43 +08001961 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301962 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001963 EXPECT_EQ(resp_data.next_data_transfer_handle,
1964 next_data_transfer_handle_resp);
1965 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1966 EXPECT_EQ(resp_data.downstream_devices_length,
1967 downstream_devices_length_resp);
1968 EXPECT_EQ(resp_data.number_of_downstream_devices,
1969 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301970
1971 foreach_pldm_downstream_device(devs, dev, rc)
1972 {
1973 struct pldm_descriptor desc;
1974
1975 EXPECT_EQ(dev.downstream_device_index, 1);
1976 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1977
1978 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1979 {
1980 static const uint32_t dmtf = htole32(412);
1981 EXPECT_EQ(desc.descriptor_type, 1);
1982 EXPECT_EQ(desc.descriptor_length, 4);
1983 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1984 }
1985 ASSERT_EQ(rc, 0);
1986 }
1987 ASSERT_EQ(rc, 0);
1988}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301989
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301990constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1991constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1992const uint32_t iana_pen_openbmc = htole16(49871u);
1993const uint32_t iana_pen_dmtf = htole16(412u);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301994
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301995TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1996{
1997 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1998 {0, 1},
1999 {1, 1},
2000 }};
2001
2002 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
2003 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2004 &iana_pen_dmtf},
2005 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2006 &iana_pen_openbmc},
2007 }};
2008
2009 constexpr uint32_t downstream_devices_len = 22;
2010 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2011 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2012 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2013 const uint32_t downstream_devices_length_resp =
2014 htole32(downstream_devices_len);
2015 constexpr uint16_t number_of_downstream_devices_resp = 2;
2016 constexpr size_t payloadLen =
2017 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2018
Patrick Williamsf37edd72024-12-18 11:22:58 -05002019 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302020 PLDM_MSG_DEFINE_P(response, payloadLen);
2021 struct pldm_downstream_device_iter devs;
2022 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302023 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302024 int rc = 0;
2025
2026 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2027 ASSERT_EQ(rc, 0);
2028
2029 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2030 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2031 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2032 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2033 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2034
2035 /* Downstream device */
2036 pldm_msgbuf_insert_uint16(buf, 0);
2037 pldm_msgbuf_insert_uint8(buf, 1);
2038
2039 /* Device descriptor */
2040 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2041 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2042 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2043
2044 /* Downstream device */
2045 pldm_msgbuf_insert_uint16(buf, 1);
2046 pldm_msgbuf_insert_uint8(buf, 1);
2047
2048 /* Device descriptor */
2049 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2050 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2051 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2052
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302053 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302054
2055 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2056 &resp_data, &devs);
2057
Unive Tien71e935c2024-11-25 17:21:43 +08002058 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302059 EXPECT_EQ(resp_data.number_of_downstream_devices,
2060 number_of_downstream_devices_resp);
2061
2062 size_t devIndex = 0;
2063 size_t descIndex = 0;
2064 foreach_pldm_downstream_device(devs, dev, rc)
2065 {
2066 struct pldm_descriptor desc;
2067
2068 ASSERT_LT(devIndex, expected_devices.size());
2069
2070 const struct pldm_downstream_device* expectedDev =
2071 &expected_devices[devIndex];
2072
2073 EXPECT_EQ(dev.downstream_device_index,
2074 expectedDev->downstream_device_index);
2075 EXPECT_EQ(dev.downstream_descriptor_count,
2076 expectedDev->downstream_descriptor_count);
2077
2078 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2079 {
2080 ASSERT_LT(descIndex, expected_descriptors.size());
2081
2082 const struct pldm_descriptor* expectedDesc =
2083 &expected_descriptors[descIndex];
2084
2085 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2086 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2087 EXPECT_EQ(memcmp(desc.descriptor_data,
2088 expectedDesc->descriptor_data,
2089 expectedDesc->descriptor_length),
2090 0);
2091
2092 descIndex++;
2093 }
2094 ASSERT_EQ(rc, 0);
2095 EXPECT_EQ(descIndex, 1 * devIndex + 1);
2096
2097 devIndex++;
2098 }
2099 ASSERT_EQ(rc, 0);
2100 EXPECT_EQ(devIndex, 2);
2101}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302102
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302103TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
2104{
2105 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2106 {0, 2},
2107 {1, 1},
2108 }};
2109
2110 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2111 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2112 &iana_pen_dmtf},
2113 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2114 &iana_pen_openbmc},
2115 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2116 &iana_pen_dmtf},
2117 }};
2118
2119 constexpr uint32_t downstream_devices_len = 30;
2120 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2121 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2122 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2123 const uint32_t downstream_devices_length_resp =
2124 htole32(downstream_devices_len);
2125 constexpr uint16_t number_of_downstream_devices_resp = 2;
2126 constexpr size_t payloadLen =
2127 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2128
Patrick Williamsf37edd72024-12-18 11:22:58 -05002129 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302130 PLDM_MSG_DEFINE_P(response, payloadLen);
2131 struct pldm_downstream_device_iter devs;
2132 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302133 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302134 int rc = 0;
2135
2136 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2137 ASSERT_EQ(rc, 0);
2138
2139 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2140 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2141 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2142 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2143 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2144
2145 /* Downstream device */
2146 pldm_msgbuf_insert_uint16(buf, 0);
2147 pldm_msgbuf_insert_uint8(buf, 2);
2148
2149 /* Device descriptor */
2150 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2151 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2152 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2153
2154 /* Device descriptor */
2155 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2156 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2157 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2158
2159 /* Downstream device */
2160 pldm_msgbuf_insert_uint16(buf, 1);
2161 pldm_msgbuf_insert_uint8(buf, 1);
2162
2163 /* Device descriptor */
2164 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2165 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2166 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2167
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302168 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302169
2170 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2171 &resp_data, &devs);
2172
Unive Tien71e935c2024-11-25 17:21:43 +08002173 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302174 EXPECT_EQ(resp_data.number_of_downstream_devices,
2175 number_of_downstream_devices_resp);
2176
2177 size_t devIndex = 0;
2178 size_t descIndex = 0;
2179 foreach_pldm_downstream_device(devs, dev, rc)
2180 {
2181 struct pldm_descriptor desc;
2182
2183 ASSERT_LT(devIndex, expected_devices.size());
2184
2185 const struct pldm_downstream_device* expectedDev =
2186 &expected_devices[devIndex];
2187
2188 EXPECT_EQ(dev.downstream_device_index,
2189 expectedDev->downstream_device_index);
2190 EXPECT_EQ(dev.downstream_descriptor_count,
2191 expectedDev->downstream_descriptor_count);
2192
2193 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2194 {
2195 ASSERT_LT(descIndex, expected_descriptors.size());
2196
2197 const struct pldm_descriptor* expectedDesc =
2198 &expected_descriptors[descIndex];
2199
2200 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2201 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2202 EXPECT_EQ(memcmp(desc.descriptor_data,
2203 expectedDesc->descriptor_data,
2204 expectedDesc->descriptor_length),
2205 0);
2206
2207 descIndex++;
2208 }
2209 ASSERT_EQ(rc, 0);
2210
2211 devIndex++;
2212 }
2213 ASSERT_EQ(rc, 0);
2214 EXPECT_EQ(devIndex, 2);
2215 EXPECT_EQ(descIndex, 3);
2216}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302217
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302218TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2219{
2220 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2221 {0, 1},
2222 {1, 2},
2223 }};
2224
2225 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2226 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2227 &iana_pen_dmtf},
2228 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2229 &iana_pen_openbmc},
2230 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2231 &iana_pen_dmtf},
2232 }};
2233
2234 constexpr uint32_t downstream_devices_len = 30;
2235 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2236 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2237 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2238 const uint32_t downstream_devices_length_resp =
2239 htole32(downstream_devices_len);
2240 constexpr uint16_t number_of_downstream_devices_resp = 2;
2241 constexpr size_t payloadLen =
2242 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2243
Patrick Williamsf37edd72024-12-18 11:22:58 -05002244 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302245 PLDM_MSG_DEFINE_P(response, payloadLen);
2246 struct pldm_downstream_device_iter devs;
2247 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302248 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302249 int rc = 0;
2250
2251 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2252 ASSERT_EQ(rc, 0);
2253
2254 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2255 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2256 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2257 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2258 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2259
2260 /* Downstream device */
2261 pldm_msgbuf_insert_uint16(buf, 0);
2262 pldm_msgbuf_insert_uint8(buf, 1);
2263
2264 /* Device descriptor */
2265 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2266 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2267 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2268
2269 /* Downstream device */
2270 pldm_msgbuf_insert_uint16(buf, 1);
2271 pldm_msgbuf_insert_uint8(buf, 2);
2272
2273 /* Device descriptor */
2274 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2275 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2276 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2277
2278 /* Device descriptor */
2279 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2280 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2281 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2282
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302283 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302284
2285 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2286 &resp_data, &devs);
2287
Unive Tien71e935c2024-11-25 17:21:43 +08002288 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302289 EXPECT_EQ(resp_data.number_of_downstream_devices,
2290 number_of_downstream_devices_resp);
2291
2292 size_t devIndex = 0;
2293 size_t descIndex = 0;
2294 foreach_pldm_downstream_device(devs, dev, rc)
2295 {
2296 struct pldm_descriptor desc;
2297
2298 ASSERT_LT(devIndex, expected_devices.size());
2299
2300 const struct pldm_downstream_device* expectedDev =
2301 &expected_devices[devIndex];
2302
2303 EXPECT_EQ(dev.downstream_device_index,
2304 expectedDev->downstream_device_index);
2305 EXPECT_EQ(dev.downstream_descriptor_count,
2306 expectedDev->downstream_descriptor_count);
2307
2308 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2309 {
2310 ASSERT_LT(descIndex, expected_descriptors.size());
2311
2312 const struct pldm_descriptor* expectedDesc =
2313 &expected_descriptors[descIndex];
2314
2315 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2316 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2317 EXPECT_EQ(memcmp(desc.descriptor_data,
2318 expectedDesc->descriptor_data,
2319 expectedDesc->descriptor_length),
2320 0);
2321
2322 descIndex++;
2323 }
2324 ASSERT_EQ(rc, 0);
2325
2326 devIndex++;
2327 }
2328 ASSERT_EQ(rc, 0);
2329 EXPECT_EQ(devIndex, 2);
2330 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002331}
2332
2333TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2334{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302335 constexpr size_t payloadLen = sizeof(uint8_t);
2336
Chris Wang458475a2024-03-26 17:59:19 +08002337 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302338 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302339 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002340
2341 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302342 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2343 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002344 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002345
2346 // Test not PLDM_SUCCESS completion code
2347 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302348 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2349 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002350 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002351 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2352
2353 // Test payload length less than minimum length
2354 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302355 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2356 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002357
Unive Tien71e935c2024-11-25 17:21:43 +08002358 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002359}
2360
2361TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2362{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302363 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002364 // 1 descriptor
2365 constexpr uint32_t actualDownstreamDevicesLen = 9;
2366 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2367 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2368 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302369 constexpr uint16_t number_of_downstream_devices_resp = 1;
2370 constexpr size_t payloadLen =
2371 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2372 actualDownstreamDevicesLen;
2373
Chris Wang458475a2024-03-26 17:59:19 +08002374 const uint32_t downstream_devices_length_resp =
2375 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002376
Andrew Jefferydec237b2024-11-08 14:33:45 +10302377 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302378 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302379 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302380 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302381 void* devicesStart = NULL;
2382 size_t devicesLen;
2383 int rc = 0;
2384
2385 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302386 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002387
2388 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2389 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2390 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2391 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2392 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302393 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002394
Andrew Jefferya1896962025-03-03 21:41:25 +10302395 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2396
Chris Wang458475a2024-03-26 17:59:19 +08002397 /** Filling descriptor data, the correctness of the downstream devices data
2398 * is not checked in this test case so filling with 0xff
2399 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302400 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2401 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002402
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302403 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2404 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002405 0);
Chris Wang458475a2024-03-26 17:59:19 +08002406}
2407
2408TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2409{
2410 constexpr uint32_t actualDownstreamDevicesLen = 0;
2411 constexpr uint16_t number_of_downstream_devices_resp = 1;
2412 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2413 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2414 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302415 constexpr size_t payloadLen =
2416 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2417
Chris Wang458475a2024-03-26 17:59:19 +08002418 const uint32_t downstream_devices_length_resp =
2419 htole32(actualDownstreamDevicesLen);
2420
Andrew Jefferydec237b2024-11-08 14:33:45 +10302421 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302422 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302423 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302424 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302425 int rc = 0;
2426
2427 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2428 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002429
2430 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2431 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2432 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2433 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2434 // Inject error buffer size
2435 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
Andrew Jefferya1896962025-03-03 21:41:25 +10302436 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang458475a2024-03-26 17:59:19 +08002437
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302438 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2439 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002440
Unive Tien71e935c2024-11-25 17:21:43 +08002441 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002442}
2443
Chris Wangb6ef35b2024-07-03 09:35:42 +08002444TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2445{
2446 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302447 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002448 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002449 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302450 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002451 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302452 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002453 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2454
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302455 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002456 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002457 EXPECT_EQ(rc, 0);
2458
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302459 std::array<uint8_t,
2460 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002461 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2462 EXPECT_EQ(requestMsg, expectedReq);
2463}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002464
Chris Wangb6ef35b2024-07-03 09:35:42 +08002465TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2466{
2467 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002468 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302469 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002470 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002471 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302472 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002473 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302474 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002475 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2476
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302477 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002478 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002479 EXPECT_EQ(rc, -EBADMSG);
2480}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002481
Chris Wangb6ef35b2024-07-03 09:35:42 +08002482TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
2483{
2484 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002485 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302486 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Andrew Jeffery53b08672025-03-04 12:26:18 +10302487 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002488 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302489 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES -
Chris Wangb6ef35b2024-07-03 09:35:42 +08002490 1 /* inject erro length*/;
2491
2492 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302493 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002494 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2495
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302496 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002497 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002498 EXPECT_EQ(rc, -EOVERFLOW);
2499}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002500
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302501TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002502{
Chris Wangb6ef35b2024-07-03 09:35:42 +08002503 constexpr uint16_t downstreamDeviceCount = 1;
2504 constexpr uint8_t activeComponentVersionStringLength = 8;
2505 constexpr uint8_t pendingComponentVersionStringLength = 8;
2506 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302507 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002508 activeComponentVersionStringLength +
2509 pendingComponentVersionStringLength;
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302510 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002511 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2512 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2513 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302514 constexpr size_t payload_len =
2515 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2516 downstreamDeviceParamTableLen;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002517
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302518 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302519 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302520 int rc = 0;
2521
2522 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302523 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002524
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302525 // Table 24
2526 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002527 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2528 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302529
2530 // Table 25
Chris Wangb6ef35b2024-07-03 09:35:42 +08002531 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2532 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2533
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302534 // Table 26
2535 pldm_msgbuf_insert_uint16(buf, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002536
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302537 // - Active metadata
2538 pldm_msgbuf_insert_uint32(buf, 0);
2539 pldm_msgbuf_insert_uint8(buf, 1);
2540 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2541 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2542 ASSERT_EQ(rc, 0);
2543
2544 // - Pending metadata
2545 pldm_msgbuf_insert_uint32(buf, 0);
2546 pldm_msgbuf_insert_uint8(buf, 1);
2547 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2548 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2549 ASSERT_EQ(rc, 0);
2550
2551 // - Methods and capabilities
2552 pldm_msgbuf_insert_uint16(buf, 1);
2553 pldm_msgbuf_insert_uint32(buf, 0);
2554
2555 // - Version strings
2556 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2557 "abcdefgh", 8);
2558 ASSERT_EQ(rc, 0);
2559 rc = pldm__msgbuf_insert_array_void(
2560 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2561 ASSERT_EQ(rc, 0);
2562
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302563 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302564 ASSERT_EQ(rc, 0);
2565
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302566 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302567 struct pldm_downstream_device_parameters_iter iter = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002568
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302569 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2570 &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002571
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302572 ASSERT_EQ(rc, 0);
2573 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002574 EXPECT_EQ(resp_data.next_data_transfer_handle,
2575 next_data_transfer_handle_resp);
2576 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2577 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302578
2579 struct pldm_downstream_device_parameters_entry entry;
2580 size_t entries = 0;
2581 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2582 {
2583 EXPECT_EQ(entry.downstream_device_index, 0);
2584 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2585 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2586 EXPECT_EQ(entry.active_comp_ver_str_len,
2587 activeComponentVersionStringLength);
2588 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2589 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2590 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2591 EXPECT_EQ(entry.pending_comp_ver_str_len,
2592 pendingComponentVersionStringLength);
2593 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2594 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2595 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2596 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2597 entry.active_comp_ver_str_len));
2598 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2599 entry.pending_comp_ver_str_len));
2600 entries++;
2601 }
2602 EXPECT_EQ(rc, 0);
2603 EXPECT_EQ(entries, 1);
2604}
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302605
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302606TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2607{
2608 /** Count is not fixed here taking it as 1, and the downstream device's
2609 * version strings length are set to 8
2610 */
2611 constexpr uint16_t downstreamDeviceCount = 2;
2612 constexpr uint8_t activeComponentVersionStringLength = 8;
2613 constexpr uint8_t pendingComponentVersionStringLength = 9;
2614 constexpr size_t downstreamDeviceParamTableLen =
2615 static_cast<size_t>(downstreamDeviceCount *
2616 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2617 activeComponentVersionStringLength +
2618 pendingComponentVersionStringLength));
2619 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2620 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2621 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2622 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2623 constexpr size_t payload_len =
2624 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2625 downstreamDeviceParamTableLen;
2626
2627 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302628 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302629 int rc = 0;
2630
2631 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302632 ASSERT_EQ(rc, 0);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302633
2634 // Table 24
2635 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2636 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2637 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2638
2639 // Table 25
2640 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2641 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2642
2643 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2644 table = {{{
2645 0,
2646 0,
2647 1,
2648 8,
2649 "20241206",
2650 0,
2651 1,
2652 9,
2653 "20241209",
2654 {1},
2655 {0},
2656 "active_0",
2657 "pending_0",
2658 },
2659 {
2660 1,
2661 0,
2662 1,
2663 8,
2664 "20241209",
2665 0,
2666 1,
2667 9,
2668 "20241206",
2669 {1},
2670 {0},
2671 "active_1",
2672 "pending_1",
2673 }}};
2674 for (const auto& e : table)
2675 {
2676 // Table 26
2677 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2678
2679 // - Active metadata
2680 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2681 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2682 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2683 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2684 sizeof(e.active_comp_release_date));
2685 ASSERT_EQ(rc, 0);
2686
2687 // - Pending metadata
2688 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2689 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2690 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2691 rc =
2692 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2693 sizeof(e.pending_comp_release_date));
2694 ASSERT_EQ(rc, 0);
2695
2696 // - Methods and capabilities
2697 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2698 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2699
2700 // - Version strings
2701 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2702 e.active_comp_ver_str,
2703 e.active_comp_ver_str_len);
2704 ASSERT_EQ(rc, 0);
2705 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2706 e.pending_comp_ver_str,
2707 e.pending_comp_ver_str_len);
2708 ASSERT_EQ(rc, 0);
2709 }
2710
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302711 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302712 ASSERT_EQ(rc, 0);
2713
2714 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2715 struct pldm_downstream_device_parameters_iter iter = {};
2716
2717 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2718 &resp_data, &iter);
2719
2720 ASSERT_EQ(rc, 0);
2721 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2722 EXPECT_EQ(resp_data.next_data_transfer_handle,
2723 next_data_transfer_handle_resp);
2724 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2725 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2726
2727 struct pldm_downstream_device_parameters_entry entry;
2728 size_t entryIndex = 0;
2729 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2730 {
2731 ASSERT_LE(entryIndex, table.size());
2732
2733 EXPECT_EQ(table[entryIndex].downstream_device_index,
2734 entry.downstream_device_index);
2735 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2736 entry.active_comp_comparison_stamp);
2737 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2738 entry.active_comp_ver_str_type);
2739 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2740 entry.active_comp_ver_str_len);
2741 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2742 &entry.active_comp_release_date[0]);
2743 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2744 entry.pending_comp_comparison_stamp);
2745 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2746 entry.pending_comp_ver_str_type);
2747 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2748 entry.pending_comp_ver_str_len);
2749 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2750 &entry.pending_comp_release_date[0]);
2751 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2752 entry.comp_activation_methods.value);
2753 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2754 entry.capabilities_during_update.value);
2755 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2756 entry.active_comp_ver_str,
2757 table[entryIndex].active_comp_ver_str_len));
2758 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2759 entry.pending_comp_ver_str,
2760 table[entryIndex].pending_comp_ver_str_len));
2761 entryIndex++;
2762 }
2763 EXPECT_EQ(rc, 0);
2764 EXPECT_EQ(entryIndex, table.size());
Chris Wangb6ef35b2024-07-03 09:35:42 +08002765}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002766
Chris Wangb6ef35b2024-07-03 09:35:42 +08002767TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2768{
2769 /** Count is not fixed here taking it as 1, and the downstream device's
2770 * version strings length are set to 8
2771 */
2772 constexpr uint16_t downstreamDeviceCount = 1;
2773 constexpr uint8_t activeComponentVersionStringLength = 8;
2774 constexpr uint8_t pendingComponentVersionStringLength = 8;
2775 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302776 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002777 activeComponentVersionStringLength +
2778 pendingComponentVersionStringLength;
2779 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2780 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2781 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2782 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2783
2784 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302785 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002786 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2787 responseMsg{};
2788
2789 int rc = 0;
2790
Andrew Jefferya1896962025-03-03 21:41:25 +10302791 PLDM_MSGBUF_DEFINE_P(buf);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002792 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2793 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10302794 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002795
2796 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2797 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2798 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2799 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2800 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
Andrew Jefferya1896962025-03-03 21:41:25 +10302801 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002802
2803 /** Filling paramter table, the correctness of the downstream devices data
2804 * is not checked in this test case so filling with 0xff
2805 */
2806 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302807 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002808 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2809 0xff);
2810
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302811 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002812 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302813 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302814 struct pldm_downstream_device_parameters_iter iter;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002815
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302816 rc = decode_get_downstream_firmware_parameters_resp(
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302817 response, responseMsg.size() - hdrSize, &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002818 EXPECT_EQ(rc, 0);
2819
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302820 struct pldm_downstream_device_parameters_entry entry;
2821 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2822 {
2823 FAIL();
2824 }
2825 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002826}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002827
Andrew Jeffery9c766792022-08-10 23:12:49 +09302828TEST(RequestUpdate, goodPathEncodeRequest)
2829{
2830 constexpr uint8_t instanceId = 1;
2831 constexpr uint32_t maxTransferSize = 512;
2832 constexpr uint16_t numOfComp = 3;
2833 constexpr uint8_t maxOutstandingTransferReq = 2;
2834 constexpr uint16_t pkgDataLen = 0x1234;
2835 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2836 constexpr uint8_t compImgSetVerStrLen =
2837 static_cast<uint8_t>(compImgSetVerStr.size());
2838 variable_field compImgSetVerStrInfo{};
2839 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302840 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302841 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2842 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2843
2844 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2845 compImgSetVerStrLen>
2846 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302847 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302848 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2849
2850 auto rc = encode_request_update_req(
2851 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2852 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2853 &compImgSetVerStrInfo, requestMsg,
2854 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2855 EXPECT_EQ(rc, PLDM_SUCCESS);
2856
2857 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2858 compImgSetVerStrLen>
2859 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2860 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2861 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2862 EXPECT_EQ(request, outRequest);
2863}
2864
2865TEST(RequestUpdate, errorPathEncodeRequest)
2866{
2867 constexpr uint8_t instanceId = 1;
2868 uint32_t maxTransferSize = 512;
2869 constexpr uint16_t numOfComp = 3;
2870 uint8_t maxOutstandingTransferReq = 2;
2871 constexpr uint16_t pkgDataLen = 0x1234;
2872 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2873 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2874 variable_field compImgSetVerStrInfo{};
2875 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302876 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302877 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2878 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2879
2880 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2881 compImgSetVerStr.size()>
2882 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302883 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302884 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2885
2886 auto rc = encode_request_update_req(
2887 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2888 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2889 requestMsg,
2890 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2891 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2892
2893 compImgSetVerStrInfo.ptr = nullptr;
2894 rc = encode_request_update_req(
2895 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2896 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2897 &compImgSetVerStrInfo, requestMsg,
2898 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2899 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2900 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302901 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302902 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2903
2904 rc = encode_request_update_req(
2905 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2906 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2907 &compImgSetVerStrInfo, nullptr,
2908 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2909 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2910
2911 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2912 maxOutstandingTransferReq, pkgDataLen,
2913 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2914 &compImgSetVerStrInfo, requestMsg, 0);
2915 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2916
2917 compImgSetVerStrLen = 0;
2918 rc = encode_request_update_req(
2919 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2920 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2921 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2922 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2923 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2924
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002925 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302926 rc = encode_request_update_req(
2927 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2928 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2929 &compImgSetVerStrInfo, nullptr,
2930 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2931 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2932 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2933
2934 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2935 rc = encode_request_update_req(
2936 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2937 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2938 &compImgSetVerStrInfo, nullptr,
2939 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2940 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2941 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2942
Andrew Jefferya1cd72b2025-05-09 12:26:06 +09302943 maxOutstandingTransferReq = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302944 rc = encode_request_update_req(
2945 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2946 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2947 &compImgSetVerStrInfo, nullptr,
2948 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2949 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2950 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2951
2952 rc = encode_request_update_req(
2953 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2954 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2955 &compImgSetVerStrInfo, nullptr,
2956 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2957 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2958}
2959
2960TEST(RequestUpdate, goodPathDecodeResponse)
2961{
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002962 /* Test a success completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302963 constexpr uint16_t fdMetaDataLen = 1024;
2964 constexpr uint8_t fdWillSendPkgData = 1;
2965 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2966 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2967
2968 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302969 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302970 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2971 uint8_t outCompletionCode = 0;
2972 uint16_t outFdMetaDataLen = 0;
2973 uint8_t outFdWillSendPkgData = 0;
2974
2975 auto rc = decode_request_update_resp(
2976 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2977 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2978 EXPECT_EQ(rc, PLDM_SUCCESS);
2979 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2980 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2981 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2982
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002983#ifdef LIBPLDM_API_TESTING
2984 /* Check the success roundtrip matches */
2985 PLDM_MSG_DEFINE_P(enc, 1000);
2986 size_t enc_payload_len = 1000;
2987 const struct pldm_request_update_resp resp_data = {
2988 .completion_code = PLDM_SUCCESS,
2989 .fd_meta_data_len = outFdMetaDataLen,
2990 .fd_will_send_pkg_data = outFdWillSendPkgData,
2991 };
2992 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2993 &enc_payload_len);
2994 EXPECT_EQ(rc, PLDM_SUCCESS);
2995 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2996 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2997 requestUpdateResponse1.end(), enc_buf + hdrSize));
2998 check_response(enc, PLDM_REQUEST_UPDATE);
2999#endif
3000
3001 /* Test a failure completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09303002 outCompletionCode = 0;
3003 outFdMetaDataLen = 0;
3004 outFdWillSendPkgData = 0;
3005
3006 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
3007 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3008 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303009 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303010 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
3011 rc = decode_request_update_resp(
3012 responseMsg2, requestUpdateResponse2.size() - hdrSize,
3013 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
3014 EXPECT_EQ(rc, PLDM_SUCCESS);
3015 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3016}
3017
3018TEST(RequestUpdate, errorPathDecodeResponse)
3019{
3020 constexpr std::array<uint8_t,
3021 hdrSize + sizeof(pldm_request_update_resp) - 1>
3022 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
3023
3024 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303025 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303026 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
3027 uint8_t outCompletionCode = 0;
3028 uint16_t outFdMetaDataLen = 0;
3029 uint8_t outFdWillSendPkgData = 0;
3030
3031 auto rc = decode_request_update_resp(
3032 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3033 &outFdMetaDataLen, &outFdWillSendPkgData);
3034 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3035
3036 rc = decode_request_update_resp(
3037 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
3038 &outFdMetaDataLen, &outFdWillSendPkgData);
3039 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3040
3041 rc = decode_request_update_resp(
3042 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3043 nullptr, &outFdWillSendPkgData);
3044 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3045
3046 rc = decode_request_update_resp(
3047 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3048 &outFdMetaDataLen, nullptr);
3049 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3050
3051 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
3052 &outFdMetaDataLen, &outFdWillSendPkgData);
3053 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3054
3055 rc = decode_request_update_resp(
3056 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3057 &outFdMetaDataLen, &outFdWillSendPkgData);
3058 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3059}
3060
Sora Su06eadd02025-05-27 11:28:51 +08003061#ifdef LIBPLDM_API_TESTING
3062TEST(RequestDownstreamDeviceUpdate, goodPathEncodeRequest)
3063{
3064 constexpr uint8_t instanceId = 1;
3065
3066 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3067 request{};
3068
3069 auto requestMsg = new (request.data()) pldm_msg;
3070
3071 constexpr struct pldm_request_downstream_device_update_req req_data = {
3072 .maximum_downstream_device_transfer_size = 512,
3073 .maximum_outstanding_transfer_requests = 2,
3074 .downstream_device_package_data_length = 0x1234,
3075 };
3076 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3077
3078 auto rc = encode_request_downstream_device_update_req(
3079 instanceId, &req_data, requestMsg, &enc_payload_len);
3080
3081 EXPECT_EQ(rc, 0);
3082
3083 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3084 outRequest{0x81, 0x05, 0x20, 0x00, 0x02, 0x00, 0x00, 0x02, 0x34, 0x12};
3085 EXPECT_EQ(request, outRequest);
3086}
3087#endif // LIBPLDM_API_TESTING
3088
3089#ifdef LIBPLDM_API_TESTING
3090TEST(RequestDownstreamDeviceUpdate, errorPathEncodeRequest)
3091{
3092 constexpr uint8_t instanceId = 1;
3093 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3094
3095 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3096 request{};
3097
3098 struct pldm_request_downstream_device_update_req req_data = {
3099 .maximum_downstream_device_transfer_size = 512,
3100 .maximum_outstanding_transfer_requests = 2,
3101 .downstream_device_package_data_length = 0x1234,
3102 };
3103
3104 auto requestMsg = new (request.data()) pldm_msg;
3105
3106 auto rc = encode_request_downstream_device_update_req(
3107 instanceId, nullptr, requestMsg, &enc_payload_len);
3108 EXPECT_EQ(rc, -EINVAL);
3109 rc = encode_request_downstream_device_update_req(
3110 instanceId, &req_data, requestMsg, &enc_payload_len);
3111 EXPECT_EQ(rc, 0);
3112
3113 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3114 nullptr, &enc_payload_len);
3115 EXPECT_EQ(rc, -EINVAL);
3116 rc = encode_request_downstream_device_update_req(
3117 instanceId, &req_data, requestMsg, &enc_payload_len);
3118 EXPECT_EQ(rc, 0);
3119
3120 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3121 requestMsg, nullptr);
3122 EXPECT_EQ(rc, -EINVAL);
3123 rc = encode_request_downstream_device_update_req(
3124 instanceId, &req_data, requestMsg, &enc_payload_len);
3125 EXPECT_EQ(rc, 0);
3126
3127 enc_payload_len =
3128 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES) - 1;
3129 rc = encode_request_downstream_device_update_req(
3130 instanceId, &req_data, requestMsg, &enc_payload_len);
3131 EXPECT_EQ(rc, -EOVERFLOW);
3132 enc_payload_len =
3133 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES);
3134 rc = encode_request_downstream_device_update_req(
3135 instanceId, &req_data, requestMsg, &enc_payload_len);
3136 EXPECT_EQ(rc, 0);
3137
3138 req_data.maximum_downstream_device_transfer_size = 31;
3139 rc = encode_request_downstream_device_update_req(
3140 instanceId, &req_data, requestMsg, &enc_payload_len);
3141 EXPECT_EQ(rc, -EINVAL);
3142 req_data.maximum_downstream_device_transfer_size =
3143 PLDM_FWUP_BASELINE_TRANSFER_SIZE;
3144
3145 req_data.maximum_outstanding_transfer_requests = 0;
3146 rc = encode_request_downstream_device_update_req(
3147 instanceId, &req_data, requestMsg, &enc_payload_len);
3148 EXPECT_EQ(rc, -EINVAL);
3149 req_data.maximum_outstanding_transfer_requests = 2;
3150 rc = encode_request_downstream_device_update_req(
3151 instanceId, &req_data, requestMsg, &enc_payload_len);
3152 EXPECT_EQ(rc, 0);
3153}
3154#endif // LIBPLDM_API_TESTING
3155
3156#ifdef LIBPLDM_API_TESTING
3157TEST(RequestDownstreamDeviceUpdate, goodPathDecodeResponse)
3158{
3159 /* Test a success completion code */
3160 constexpr uint16_t ddMetaDataLen = 1024;
3161 constexpr uint8_t ddWillSendPkgData = 1;
3162 constexpr uint16_t getPkgDataMaxTransferSize = 512;
3163 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3164 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00,
3165 0x04, 0x01, 0x00, 0x02};
3166
3167 auto responseMsg1 = new (requestUpdateResponse1.data()) pldm_msg;
3168
3169 struct pldm_request_downstream_device_update_resp resp_data1 = {
3170 .completion_code = 0,
3171 .downstream_device_meta_data_length = 0,
3172 .downstream_device_will_send_get_package_data = 0,
3173 .get_package_data_maximum_transfer_size = 0};
3174
3175 auto rc = decode_request_downstream_device_update_resp(
3176 responseMsg1, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3177 &resp_data1);
3178 EXPECT_EQ(rc, 0);
3179 EXPECT_EQ(resp_data1.completion_code, PLDM_SUCCESS);
3180 EXPECT_EQ(resp_data1.downstream_device_meta_data_length, ddMetaDataLen);
3181 EXPECT_EQ(resp_data1.downstream_device_will_send_get_package_data,
3182 ddWillSendPkgData);
3183 EXPECT_EQ(resp_data1.get_package_data_maximum_transfer_size,
3184 getPkgDataMaxTransferSize);
3185
3186 /* Test a failure completion code */
3187 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3188 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3189
3190 auto responseMsg2 = new (requestUpdateResponse2.data()) pldm_msg;
3191
3192 struct pldm_request_downstream_device_update_resp resp_data2 = {
3193 .completion_code = 0,
3194 .downstream_device_meta_data_length = 0,
3195 .downstream_device_will_send_get_package_data = 0,
3196 .get_package_data_maximum_transfer_size = 0};
3197
3198 rc = decode_request_downstream_device_update_resp(
3199 responseMsg2, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3200 &resp_data2);
3201 EXPECT_EQ(rc, 0);
3202 EXPECT_EQ(resp_data2.completion_code, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3203}
3204#endif // LIBPLDM_API_TESTING
3205
3206#ifdef LIBPLDM_API_TESTING
3207TEST(RequestDownstreamDeviceUpdate, errorPathDecodeResponse)
3208{
3209 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3210 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00,
3211 0x04, 0x01, 0x00, 0x02};
3212
3213 auto responseMsg = new (requestUpdateResponse.data()) pldm_msg;
3214
3215 struct pldm_request_downstream_device_update_resp resp_data = {
3216 .completion_code = 0,
3217 .downstream_device_meta_data_length = 0,
3218 .downstream_device_will_send_get_package_data = 0,
3219 .get_package_data_maximum_transfer_size = 0};
3220
3221 auto rc = decode_request_downstream_device_update_resp(
3222 nullptr, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, &resp_data);
3223 EXPECT_EQ(rc, -EINVAL);
3224
3225 rc = decode_request_downstream_device_update_resp(
3226 responseMsg, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, nullptr);
3227 EXPECT_EQ(rc, -EINVAL);
3228
3229 rc = decode_request_downstream_device_update_resp(responseMsg, 0,
3230 &resp_data);
3231 EXPECT_EQ(rc, -EOVERFLOW);
3232}
3233#endif // LIBPLDM_API_TESTING
3234
Andrew Jeffery9c766792022-08-10 23:12:49 +09303235TEST(PassComponentTable, goodPathEncodeRequest)
3236{
3237 constexpr uint8_t instanceId = 1;
3238 constexpr uint16_t compIdentifier = 400;
3239 constexpr uint8_t compClassificationIndex = 40;
3240 constexpr uint32_t compComparisonStamp = 0x12345678;
3241 constexpr std::string_view compVerStr = "0penBmcv1.1";
3242 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3243 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303244 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303245 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3246 compVerStrInfo.length = compVerStrLen;
3247
3248 std::array<uint8_t,
3249 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3250 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303251 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303252 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3253
3254 auto rc = encode_pass_component_table_req(
3255 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3256 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3257 compVerStrLen, &compVerStrInfo, requestMsg,
3258 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3259 EXPECT_EQ(rc, PLDM_SUCCESS);
3260
3261 std::array<uint8_t,
3262 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003263 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
3264 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
3265 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303266 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003267
3268#ifdef LIBPLDM_API_TESTING
3269 /* Check the roundtrip */
3270 struct pldm_pass_component_table_req_full req;
3271 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3272 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3273 rc =
3274 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
3275 ASSERT_EQ(rc, 0);
3276
3277 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
3278 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3279 EXPECT_EQ(req.comp_identifier, compIdentifier);
3280 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3281 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3282 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3283 EXPECT_EQ(req.version.str_len, compVerStrLen);
3284 EXPECT_TRUE(std::equal(req.version.str_data,
3285 req.version.str_data + req.version.str_len,
3286 compVerStr.data()));
3287#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303288}
3289
3290TEST(PassComponentTable, errorPathEncodeRequest)
3291{
3292 constexpr uint8_t instanceId = 1;
3293 constexpr uint16_t compIdentifier = 400;
3294 constexpr uint8_t compClassificationIndex = 40;
3295 constexpr uint32_t compComparisonStamp = 0x12345678;
3296 constexpr std::string_view compVerStr = "0penBmcv1.1";
3297 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3298 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303299 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303300 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3301 compVerStrInfo.length = compVerStrLen;
3302
3303 std::array<uint8_t,
3304 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3305 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303306 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303307 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3308
3309 auto rc = encode_pass_component_table_req(
3310 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3311 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3312 compVerStrLen, nullptr, requestMsg,
3313 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3314 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3315
3316 compVerStrInfo.ptr = nullptr;
3317 rc = encode_pass_component_table_req(
3318 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3319 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3320 compVerStrLen, &compVerStrInfo, requestMsg,
3321 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3322 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303323 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303324 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3325
3326 rc = encode_pass_component_table_req(
3327 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3328 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3329 compVerStrLen, &compVerStrInfo, nullptr,
3330 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3331 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3332
3333 rc = encode_pass_component_table_req(
3334 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3335 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3336 compVerStrLen, &compVerStrInfo, requestMsg,
3337 sizeof(pldm_pass_component_table_req));
3338 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3339
3340 rc = encode_pass_component_table_req(
3341 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3342 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3343 &compVerStrInfo, requestMsg,
3344 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3345 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3346
3347 rc = encode_pass_component_table_req(
3348 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3349 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3350 compVerStrLen - 1, &compVerStrInfo, requestMsg,
3351 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3352 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3353
3354 rc = encode_pass_component_table_req(
3355 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3356 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3357 compVerStrLen, &compVerStrInfo, requestMsg,
3358 sizeof(pldm_pass_component_table_req) + compVerStrLen);
Manojkiran Eda3643e742025-05-19 12:03:54 +05303359 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG);
Andrew Jeffery9c766792022-08-10 23:12:49 +09303360
3361 rc = encode_pass_component_table_req(
3362 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3363 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3364 compVerStrLen, &compVerStrInfo, requestMsg,
3365 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3366 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3367}
3368
3369TEST(PassComponentTable, goodPathDecodeResponse)
3370{
3371 constexpr std::array<uint8_t,
3372 hdrSize + sizeof(pldm_pass_component_table_resp)>
3373 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3374 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303375 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303376 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3377
3378 uint8_t completionCode = 0;
3379 uint8_t compResp = 0;
3380 uint8_t compRespCode = 0;
3381
3382 auto rc = decode_pass_component_table_resp(
3383 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3384 &compResp, &compRespCode);
3385
3386 EXPECT_EQ(rc, PLDM_SUCCESS);
3387 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3388 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3389 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3390
3391 constexpr std::array<uint8_t,
3392 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003393 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303394 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303395 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303396 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3397 rc = decode_pass_component_table_resp(
3398 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3399 &compResp, &compRespCode);
3400
3401 EXPECT_EQ(rc, PLDM_SUCCESS);
3402 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3403 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3404 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3405
3406 constexpr std::array<uint8_t,
3407 hdrSize + sizeof(pldm_pass_component_table_resp)>
3408 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3409 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303410 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303411 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3412
3413 rc = decode_pass_component_table_resp(
3414 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3415 &compResp, &compRespCode);
3416
3417 EXPECT_EQ(rc, PLDM_SUCCESS);
3418 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3419}
3420
3421TEST(PassComponentTable, errorPathDecodeResponse)
3422{
3423 constexpr std::array<uint8_t,
3424 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3425 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3426 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303427 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303428 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3429
3430 uint8_t completionCode = 0;
3431 uint8_t compResp = 0;
3432 uint8_t compRespCode = 0;
3433
3434 auto rc = decode_pass_component_table_resp(
3435 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3436 &compResp, &compRespCode);
3437 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3438
3439 rc = decode_pass_component_table_resp(
3440 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3441 &compResp, &compRespCode);
3442 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3443
3444 rc = decode_pass_component_table_resp(
3445 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3446 &completionCode, nullptr, &compRespCode);
3447 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3448
3449 rc = decode_pass_component_table_resp(
3450 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3451 &completionCode, &compResp, nullptr);
3452 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3453
3454 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3455 &compResp, &compRespCode);
3456 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3457
3458 rc = decode_pass_component_table_resp(
3459 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3460 &completionCode, &compResp, &compRespCode);
3461 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3462
3463 constexpr std::array<uint8_t,
3464 hdrSize + sizeof(pldm_pass_component_table_resp)>
3465 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3466 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303467 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303468 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3469 rc = decode_pass_component_table_resp(
3470 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3471 &compResp, &compRespCode);
3472 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3473
3474 constexpr std::array<uint8_t,
3475 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003476 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303477 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303478 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303479 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3480 rc = decode_pass_component_table_resp(
3481 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3482 &compResp, &compRespCode);
3483 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3484
3485 constexpr std::array<uint8_t,
3486 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003487 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303488 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303489 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303490 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3491 rc = decode_pass_component_table_resp(
3492 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3493 &compResp, &compRespCode);
3494 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3495}
3496
3497TEST(UpdateComponent, goodPathEncodeRequest)
3498{
3499 constexpr uint8_t instanceId = 2;
3500 constexpr uint16_t compIdentifier = 500;
3501 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003502 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303503 constexpr uint32_t compImageSize = 4096;
3504 constexpr bitfield32_t updateOptionFlags{1};
3505 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3506 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3507 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303508 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303509 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3510 compVerStrInfo.length = compVerStrLen;
3511
3512 std::array<uint8_t,
3513 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3514 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303515 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303516 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3517
3518 auto rc = encode_update_component_req(
3519 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3520 compComparisonStamp, compImageSize, updateOptionFlags,
3521 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3522 sizeof(pldm_update_component_req) + compVerStrLen);
3523 EXPECT_EQ(rc, PLDM_SUCCESS);
3524
3525 std::array<uint8_t,
3526 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003527 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3528 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3529 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3530 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303531 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003532
3533#ifdef LIBPLDM_API_TESTING
3534 /* Check the roundtrip */
3535 struct pldm_update_component_req_full req;
3536 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3537 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3538 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3539 ASSERT_EQ(rc, 0);
3540
3541 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3542 EXPECT_EQ(req.comp_identifier, compIdentifier);
3543 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3544 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3545 EXPECT_EQ(req.comp_image_size, compImageSize);
3546 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3547 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3548 EXPECT_EQ(req.version.str_len, compVerStrLen);
3549 EXPECT_TRUE(std::equal(req.version.str_data,
3550 req.version.str_data + req.version.str_len,
3551 compVerStr.data()));
3552#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303553}
3554
3555TEST(UpdateComponent, errorPathEncodeRequest)
3556{
3557 constexpr uint8_t instanceId = 2;
3558 constexpr uint16_t compIdentifier = 500;
3559 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003560 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303561 constexpr uint32_t compImageSize = 4096;
3562 constexpr bitfield32_t updateOptionFlags{1};
3563 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3564 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3565 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303566 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303567 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3568 compVerStrInfo.length = compVerStrLen;
3569
3570 std::array<uint8_t,
3571 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3572 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303573 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303574 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3575
3576 auto rc = encode_update_component_req(
3577 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3578 compComparisonStamp, compImageSize, updateOptionFlags,
3579 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3580 sizeof(pldm_update_component_req) + compVerStrLen);
3581 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3582
3583 compVerStrInfo.ptr = nullptr;
3584 rc = encode_update_component_req(
3585 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3586 compComparisonStamp, compImageSize, updateOptionFlags,
3587 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3588 sizeof(pldm_update_component_req) + compVerStrLen);
3589 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303590 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303591 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3592
3593 rc = encode_update_component_req(
3594 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3595 compComparisonStamp, compImageSize, updateOptionFlags,
3596 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3597 sizeof(pldm_update_component_req) + compVerStrLen);
3598 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3599
3600 rc = encode_update_component_req(
3601 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3602 compComparisonStamp, compImageSize, updateOptionFlags,
3603 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3604 sizeof(pldm_update_component_req));
3605 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3606
3607 rc = encode_update_component_req(
3608 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3609 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3610 compVerStrLen, &compVerStrInfo, requestMsg,
3611 sizeof(pldm_update_component_req) + compVerStrLen);
3612 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3613
3614 rc = encode_update_component_req(
3615 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3616 compComparisonStamp, compImageSize, updateOptionFlags,
3617 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3618 sizeof(pldm_update_component_req) + compVerStrLen);
3619 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3620
3621 rc = encode_update_component_req(
3622 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3623 compComparisonStamp, compImageSize, updateOptionFlags,
3624 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3625 sizeof(pldm_update_component_req) + compVerStrLen);
3626 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3627
3628 rc = encode_update_component_req(
3629 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3630 compComparisonStamp, compImageSize, updateOptionFlags,
3631 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3632 sizeof(pldm_update_component_req) + compVerStrLen);
3633 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3634}
3635
3636TEST(UpdateComponent, goodPathDecodeResponse)
3637{
3638 constexpr std::bitset<32> forceUpdateComp{1};
3639 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3640 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3641 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3642 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3643 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303644 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303645 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3646
3647 uint8_t completionCode = 0;
3648 uint8_t compCompatibilityResp = 0;
3649 uint8_t compCompatibilityRespCode = 0;
3650 bitfield32_t updateOptionFlagsEnabled{};
3651 uint16_t timeBeforeReqFWData = 0;
3652
3653 auto rc = decode_update_component_resp(
3654 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3655 &compCompatibilityResp, &compCompatibilityRespCode,
3656 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3657
3658 EXPECT_EQ(rc, PLDM_SUCCESS);
3659 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3660 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3661 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3662 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3663 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3664
3665 constexpr std::bitset<32> noFlags{};
3666 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3667 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3668 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3670 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303671 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303672 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3673 rc = decode_update_component_resp(
3674 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3675 &compCompatibilityResp, &compCompatibilityRespCode,
3676 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3677
3678 EXPECT_EQ(rc, PLDM_SUCCESS);
3679 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3680 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3681 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3682 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3683 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3684
3685 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3686 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3687 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303688 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303689 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3690
3691 rc = decode_update_component_resp(
3692 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3693 &compCompatibilityResp, &compCompatibilityRespCode,
3694 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3695
3696 EXPECT_EQ(rc, PLDM_SUCCESS);
3697 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3698}
3699
3700TEST(UpdateComponent, errorPathDecodeResponse)
3701{
3702 constexpr std::array<uint8_t,
3703 hdrSize + sizeof(pldm_update_component_resp) - 1>
3704 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3705 0x00, 0x00, 0x00, 0x00, 0x00};
3706 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303707 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303708 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3709
3710 uint8_t completionCode = 0;
3711 uint8_t compCompatibilityResp = 0;
3712 uint8_t compCompatibilityRespCode = 0;
3713 bitfield32_t updateOptionFlagsEnabled{};
3714 uint16_t timeBeforeReqFWData = 0;
3715
3716 auto rc = decode_update_component_resp(
3717 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3718 &compCompatibilityResp, &compCompatibilityRespCode,
3719 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3720 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3721
3722 rc = decode_update_component_resp(
3723 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3724 &compCompatibilityResp, &compCompatibilityRespCode,
3725 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3726 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3727
3728 rc = decode_update_component_resp(
3729 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3730 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3731 &timeBeforeReqFWData);
3732 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3733
3734 rc = decode_update_component_resp(
3735 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3736 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3737 &timeBeforeReqFWData);
3738 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3739
3740 rc = decode_update_component_resp(
3741 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3742 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3743 &timeBeforeReqFWData);
3744 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3745
3746 rc = decode_update_component_resp(
3747 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3748 &compCompatibilityResp, &compCompatibilityRespCode,
3749 &updateOptionFlagsEnabled, nullptr);
3750 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3751
3752 rc = decode_update_component_resp(
3753 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3754 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3755 &timeBeforeReqFWData);
3756 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3757
3758 rc = decode_update_component_resp(
3759 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3760 &compCompatibilityResp, &compCompatibilityRespCode,
3761 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3762 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3763
3764 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3765 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3766 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3767 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303768 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303769 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3770 rc = decode_update_component_resp(
3771 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3772 &compCompatibilityResp, &compCompatibilityRespCode,
3773 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3774 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3775
3776 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003777 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303778 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3779 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303780 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303781 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3782 rc = decode_update_component_resp(
3783 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3784 &compCompatibilityResp, &compCompatibilityRespCode,
3785 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3786 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3787
3788 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003789 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303790 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3791 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303792 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303793 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3794 rc = decode_update_component_resp(
3795 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3796 &compCompatibilityResp, &compCompatibilityRespCode,
3797 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3798 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3799}
3800
3801TEST(RequestFirmwareData, goodPathDecodeRequest)
3802{
3803 constexpr uint32_t offset = 300;
3804 constexpr uint32_t length = 255;
3805 constexpr std::array<uint8_t,
3806 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003807 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3808 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303809 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303810 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3811
3812 uint32_t outOffset = 0;
3813 uint32_t outLength = 0;
3814 auto rc = decode_request_firmware_data_req(
3815 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3816 &outLength);
3817
3818 EXPECT_EQ(rc, PLDM_SUCCESS);
3819 EXPECT_EQ(outOffset, offset);
3820 EXPECT_EQ(outLength, length);
3821}
3822
3823TEST(RequestFirmwareData, errorPathDecodeRequest)
3824{
3825 constexpr std::array<uint8_t,
3826 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003827 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3828 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303829 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303830 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3831
3832 uint32_t outOffset = 0;
3833 uint32_t outLength = 0;
3834 auto rc = decode_request_firmware_data_req(
3835 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3836 &outLength);
3837 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3838
3839 rc = decode_request_firmware_data_req(
3840 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3841 &outLength);
3842 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3843
3844 rc = decode_request_firmware_data_req(
3845 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3846 nullptr);
3847 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3848
3849 rc = decode_request_firmware_data_req(
3850 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3851 &outLength);
3852 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3853
3854 rc = decode_request_firmware_data_req(
3855 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3856 &outLength);
3857 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3858}
3859
3860TEST(RequestFirmwareData, goodPathEncodeResponse)
3861{
3862 constexpr uint8_t instanceId = 3;
3863 constexpr uint8_t completionCode = PLDM_SUCCESS;
3864 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3865 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3866 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003867 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3868 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3869 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3870 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303871 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3872 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3873 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003874 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3875 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3876 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3877 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303878 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303879 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3880 auto rc = encode_request_firmware_data_resp(
3881 instanceId, completionCode, responseMsg1,
3882 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3883 EXPECT_EQ(rc, PLDM_SUCCESS);
3884 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3885
3886 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3887 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3888 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3889 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303890 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303891 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3892 rc = encode_request_firmware_data_resp(
3893 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3894 sizeof(completionCode));
3895 EXPECT_EQ(rc, PLDM_SUCCESS);
3896 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3897}
3898
3899TEST(RequestFirmwareData, errorPathEncodeResponse)
3900{
3901 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303902 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303903 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3904 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3905 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3906
3907 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3908 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3909}
3910
3911TEST(TransferComplete, goodPathDecodeRequest)
3912{
3913 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3914 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3915 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3916 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303917 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303918 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3919 uint8_t outTransferResult = 0;
3920
3921 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3922 &outTransferResult);
3923 EXPECT_EQ(rc, PLDM_SUCCESS);
3924 EXPECT_EQ(outTransferResult, transferResult);
3925
3926 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3927 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3928 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303929 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303930 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3931 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3932 &outTransferResult);
3933 EXPECT_EQ(rc, PLDM_SUCCESS);
3934 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3935}
3936
3937TEST(TransferComplete, errorPathDecodeRequest)
3938{
3939 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3940 0x00};
3941 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303942 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303943 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3944 uint8_t outTransferResult = 0;
3945
3946 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3947 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3948
3949 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3950 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3951
3952 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3953 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3954}
3955
3956TEST(TransferComplete, goodPathEncodeResponse)
3957{
3958 constexpr uint8_t instanceId = 4;
3959 constexpr uint8_t completionCode = PLDM_SUCCESS;
3960 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3961 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3962 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3963 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3964 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303965 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303966 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3967 auto rc = encode_transfer_complete_resp(
3968 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3969 EXPECT_EQ(rc, PLDM_SUCCESS);
3970 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3971
3972 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3973 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3974 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3975 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3976 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303977 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303978 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3979 rc = encode_transfer_complete_resp(instanceId,
3980 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3981 responseMsg2, sizeof(completionCode));
3982 EXPECT_EQ(rc, PLDM_SUCCESS);
3983 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3984}
3985
3986TEST(TransferComplete, errorPathEncodeResponse)
3987{
3988 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3989 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303990 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303991 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3992 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3993 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3994
3995 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3996 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3997}
3998
3999TEST(VerifyComplete, goodPathDecodeRequest)
4000{
4001 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
4002 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
4003 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
4004 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304005 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304006 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
4007 uint8_t outVerifyResult = 0;
4008
4009 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
4010 &outVerifyResult);
4011 EXPECT_EQ(rc, PLDM_SUCCESS);
4012 EXPECT_EQ(outVerifyResult, verifyResult);
4013
4014 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
4015 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
4016 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304017 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304018 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
4019 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
4020 &outVerifyResult);
4021 EXPECT_EQ(rc, PLDM_SUCCESS);
4022 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
4023}
4024
4025TEST(VerifyComplete, errorPathDecodeRequest)
4026{
4027 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
4028 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304029 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304030 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
4031 uint8_t outVerifyResult = 0;
4032
4033 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
4034 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4035
4036 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
4037 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4038
4039 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
4040 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4041}
4042
4043TEST(VerifyComplete, goodPathEncodeResponse)
4044{
4045 constexpr uint8_t instanceId = 5;
4046 constexpr uint8_t completionCode = PLDM_SUCCESS;
4047 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4048 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
4049 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4050 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4051 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304052 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304053 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
4054 auto rc = encode_verify_complete_resp(instanceId, completionCode,
4055 responseMsg1, sizeof(completionCode));
4056 EXPECT_EQ(rc, PLDM_SUCCESS);
4057 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
4058
4059 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4060 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
4061 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4062 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4063 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304064 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304065 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
4066 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4067 responseMsg2, sizeof(completionCode));
4068 EXPECT_EQ(rc, PLDM_SUCCESS);
4069 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
4070}
4071
4072TEST(VerifyComplete, errorPathEncodeResponse)
4073{
4074 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
4075 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304076 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304077 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
4078 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4079 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4080
4081 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4082 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4083}
4084
4085TEST(ApplyComplete, goodPathDecodeRequest)
4086{
4087 constexpr uint8_t applyResult1 =
4088 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
4089 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
4090 constexpr std::bitset<16> compActivationModification1{0x30};
4091 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4092 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
4093 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304094 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304095 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4096 uint8_t outApplyResult = 0;
4097 bitfield16_t outCompActivationModification{};
4098 auto rc = decode_apply_complete_req(
4099 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
4100 &outCompActivationModification);
4101 EXPECT_EQ(rc, PLDM_SUCCESS);
4102 EXPECT_EQ(outApplyResult, applyResult1);
4103 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
4104
4105 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
4106 constexpr std::bitset<16> compActivationModification2{};
4107 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4108 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4109 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304110 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304111 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4112 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4113 &outApplyResult,
4114 &outCompActivationModification);
4115 EXPECT_EQ(rc, PLDM_SUCCESS);
4116 EXPECT_EQ(outApplyResult, applyResult2);
4117 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
4118}
4119
4120TEST(ApplyComplete, errorPathDecodeRequest)
4121{
4122 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
4123 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304124 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304125 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4126 uint8_t outApplyResult = 0;
4127 bitfield16_t outCompActivationModification{};
4128
4129 auto rc = decode_apply_complete_req(
4130 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
4131 &outCompActivationModification);
4132 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4133
4134 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4135 nullptr, &outCompActivationModification);
4136 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4137
4138 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4139 &outApplyResult, nullptr);
4140 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4141
4142 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
4143 &outCompActivationModification);
4144 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4145
4146 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4147 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
4148 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304149 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304150 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4151 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4152 &outApplyResult,
4153 &outCompActivationModification);
4154 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4155}
4156
4157TEST(ApplyComplete, goodPathEncodeResponse)
4158{
4159 constexpr uint8_t instanceId = 6;
4160 constexpr uint8_t completionCode = PLDM_SUCCESS;
4161 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4162 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
4163 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4164 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4165 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304166 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304167 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
4168 auto rc = encode_apply_complete_resp(instanceId, completionCode,
4169 responseMsg1, sizeof(completionCode));
4170 EXPECT_EQ(rc, PLDM_SUCCESS);
4171 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
4172
4173 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4174 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
4175 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4176 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4177 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304178 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304179 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
4180 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4181 responseMsg2, sizeof(completionCode));
4182 EXPECT_EQ(rc, PLDM_SUCCESS);
4183 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
4184}
4185
4186TEST(ApplyComplete, errorPathEncodeResponse)
4187{
4188 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
4189 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304190 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304191 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
4192 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4193 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4194
4195 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4196 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4197}
4198
4199TEST(ActivateFirmware, goodPathEncodeRequest)
4200{
4201 constexpr uint8_t instanceId = 7;
4202
4203 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304204 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304205 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4206
4207 auto rc = encode_activate_firmware_req(
4208 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
4209 sizeof(pldm_activate_firmware_req));
4210 EXPECT_EQ(rc, PLDM_SUCCESS);
4211
4212 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004213 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304214 EXPECT_EQ(request, outRequest);
4215}
4216
4217TEST(ActivateFirmware, errorPathEncodeRequest)
4218{
4219 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304220 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304221 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4222
4223 auto rc = encode_activate_firmware_req(
4224 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
4225 sizeof(pldm_activate_firmware_req));
4226 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4227
4228 rc = encode_activate_firmware_req(
4229 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
4230 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4231
4232 rc = encode_activate_firmware_req(0, 2, requestMsg,
4233 sizeof(pldm_activate_firmware_req));
4234 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4235}
4236
4237TEST(ActivateFirmware, goodPathDecodeResponse)
4238{
4239 constexpr uint16_t estimatedTimeForActivation100s = 100;
4240 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4241 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
4242 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304243 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304244 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
4245
4246 uint8_t completionCode = 0;
4247 uint16_t estimatedTimeForActivation = 0;
4248
4249 auto rc = decode_activate_firmware_resp(
4250 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
4251 &estimatedTimeForActivation);
4252
4253 EXPECT_EQ(rc, PLDM_SUCCESS);
4254 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4255 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
4256
4257 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4258 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
4259 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304260 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304261 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse2.data());
4262
4263 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
4264 &completionCode,
4265 &estimatedTimeForActivation);
4266
4267 EXPECT_EQ(rc, PLDM_SUCCESS);
4268 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
4269}
4270
4271TEST(ActivateFirmware, errorPathDecodeResponse)
4272{
4273 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4274 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4275 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304276 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304277 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
4278
4279 uint8_t completionCode = 0;
4280 uint16_t estimatedTimeForActivation = 0;
4281
4282 auto rc = decode_activate_firmware_resp(
4283 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
4284 &estimatedTimeForActivation);
4285 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4286
4287 rc = decode_activate_firmware_resp(responseMsg,
4288 sizeof(pldm_activate_firmware_resp),
4289 nullptr, &estimatedTimeForActivation);
4290 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4291
4292 rc = decode_activate_firmware_resp(responseMsg,
4293 sizeof(pldm_activate_firmware_resp),
4294 &completionCode, nullptr);
4295 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4296
4297 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
4298 &estimatedTimeForActivation);
4299 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4300
4301 rc = decode_activate_firmware_resp(
4302 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
4303 &estimatedTimeForActivation);
4304 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4305}
4306
4307TEST(GetStatus, goodPathEncodeRequest)
4308{
4309 constexpr uint8_t instanceId = 8;
4310 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304311 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304312 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4313
4314 auto rc = encode_get_status_req(instanceId, requestMsg,
4315 PLDM_GET_STATUS_REQ_BYTES);
4316 EXPECT_EQ(rc, PLDM_SUCCESS);
4317
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004318 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304319 EXPECT_EQ(request, outRequest);
4320}
4321
4322TEST(GetStatus, errorPathEncodeRequest)
4323{
4324 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304325 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304326 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4327
4328 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4329 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4330
4331 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4332 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4333}
4334
4335TEST(GetStatus, goodPathDecodeResponse)
4336{
4337 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4338 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4339 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4340 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4341 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304342 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304343 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4344
4345 uint8_t completionCode = 0;
4346 uint8_t currentState = 0;
4347 uint8_t previousState = 0;
4348 uint8_t auxState = 0;
4349 uint8_t auxStateStatus = 0;
4350 uint8_t progressPercent = 0;
4351 uint8_t reasonCode = 0;
4352 bitfield32_t updateOptionFlagsEnabled{0};
4353
4354 auto rc = decode_get_status_resp(
4355 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4356 &currentState, &previousState, &auxState, &auxStateStatus,
4357 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4358
4359 EXPECT_EQ(rc, PLDM_SUCCESS);
4360 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4361 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4362 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4363 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4364 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4365 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4366 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4367 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4368
4369 // Bit position 0 - Force update of component – FD will perform a force
4370 // update of the component.
4371 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4372 constexpr uint8_t progressPercent2 = 50;
4373 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4374 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4375 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4376 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304377 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304378 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4379
4380 rc = decode_get_status_resp(
4381 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4382 &currentState, &previousState, &auxState, &auxStateStatus,
4383 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4384
4385 EXPECT_EQ(rc, PLDM_SUCCESS);
4386 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4387 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4388 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4389 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4390 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4391 EXPECT_EQ(progressPercent, progressPercent2);
4392 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4393 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4394
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004395#ifdef LIBPLDM_API_TESTING
4396 /* Check the roundtrip */
4397 PLDM_MSG_DEFINE_P(enc, 1000);
4398 size_t enc_payload_len = 1000;
4399 const struct pldm_get_status_resp status_enc = {
4400 .completion_code = PLDM_SUCCESS,
4401 .current_state = currentState,
4402 .previous_state = previousState,
4403 .aux_state = auxState,
4404 .aux_state_status = auxStateStatus,
4405 .progress_percent = progressPercent,
4406 .reason_code = reasonCode,
4407 .update_option_flags_enabled = updateOptionFlagsEnabled,
4408 };
4409 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4410 &enc_payload_len);
4411 EXPECT_EQ(rc, PLDM_SUCCESS);
4412 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4413 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4414 getStatusResponse2.end(), enc_buf + hdrSize));
4415 check_response(enc, PLDM_GET_STATUS);
4416#endif
4417
4418 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304419 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4420 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4421 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304422 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304423 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4424 rc = decode_get_status_resp(
4425 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4426 &currentState, &previousState, &auxState, &auxStateStatus,
4427 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4428 EXPECT_EQ(rc, PLDM_SUCCESS);
4429 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4430}
4431
4432TEST(GetStatus, errorPathDecodeResponse)
4433{
4434 uint8_t completionCode = 0;
4435 uint8_t currentState = 0;
4436 uint8_t previousState = 0;
4437 uint8_t auxState = 0;
4438 uint8_t auxStateStatus = 0;
4439 uint8_t progressPercent = 0;
4440 uint8_t reasonCode = 0;
4441 bitfield32_t updateOptionFlagsEnabled{0};
4442
4443 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4444 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304445 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304446 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4447
4448 auto rc = decode_get_status_resp(
4449 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4450 &currentState, &previousState, &auxState, &auxStateStatus,
4451 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4452 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4453
4454 rc = decode_get_status_resp(
4455 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4456 &currentState, &previousState, &auxState, &auxStateStatus,
4457 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4458 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4459
4460 rc = decode_get_status_resp(
4461 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4462 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4463 &reasonCode, &updateOptionFlagsEnabled);
4464 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4465
4466 rc = decode_get_status_resp(
4467 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4468 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4469 &reasonCode, &updateOptionFlagsEnabled);
4470 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4471
4472 rc = decode_get_status_resp(
4473 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4474 &currentState, &previousState, nullptr, &auxStateStatus,
4475 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4476 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4477
4478 rc = decode_get_status_resp(
4479 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4480 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4481 &reasonCode, &updateOptionFlagsEnabled);
4482 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4483
4484 rc = decode_get_status_resp(
4485 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4486 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4487 &reasonCode, &updateOptionFlagsEnabled);
4488 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4489
4490 rc = decode_get_status_resp(
4491 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4492 &currentState, &previousState, &auxState, &auxStateStatus,
4493 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4494 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4495
4496 rc = decode_get_status_resp(
4497 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4498 &currentState, &previousState, &auxState, &auxStateStatus,
4499 &progressPercent, &reasonCode, nullptr);
4500 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4501
4502 rc = decode_get_status_resp(
4503 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4504 &currentState, &previousState, &auxState, &auxStateStatus,
4505 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4506 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4507
4508 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4509 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4511 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304512 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304513 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4514 rc = decode_get_status_resp(
4515 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4516 &currentState, &previousState, &auxState, &auxStateStatus,
4517 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4518 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4519
4520 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4521 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4522 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4523 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304524 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304525 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4526 rc = decode_get_status_resp(
4527 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4528 &currentState, &previousState, &auxState, &auxStateStatus,
4529 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4530 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4531
4532 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4533 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4535 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304536 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304537 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4538 rc = decode_get_status_resp(
4539 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4540 &currentState, &previousState, &auxState, &auxStateStatus,
4541 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4542 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4543
4544 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4545 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4547 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304548 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304549 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4550 rc = decode_get_status_resp(
4551 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4552 &currentState, &previousState, &auxState, &auxStateStatus,
4553 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4554 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4555
4556 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4557 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004558 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304559 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304560 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304561 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4562 rc = decode_get_status_resp(
4563 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4564 &currentState, &previousState, &auxState, &auxStateStatus,
4565 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4566 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4567
4568 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4569 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4570 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4571 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304572 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304573 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4574 rc = decode_get_status_resp(
4575 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4576 &currentState, &previousState, &auxState, &auxStateStatus,
4577 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4578 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4579
4580 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4581 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004582 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304583 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304584 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304585 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4586 rc = decode_get_status_resp(
4587 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4588 &currentState, &previousState, &auxState, &auxStateStatus,
4589 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4590 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4591
4592 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4593 // IDLE
4594 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4595 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4597 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304598 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304599 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4600 rc = decode_get_status_resp(
4601 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4602 &currentState, &previousState, &auxState, &auxStateStatus,
4603 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4604 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4605}
4606
4607TEST(CancelUpdateComponent, goodPathEncodeRequest)
4608{
4609 constexpr uint8_t instanceId = 9;
4610 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304611 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304612 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4613
4614 auto rc = encode_cancel_update_component_req(
4615 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4616 EXPECT_EQ(rc, PLDM_SUCCESS);
4617
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004618 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304619 EXPECT_EQ(request, outRequest);
4620}
4621
4622TEST(CancelUpdateComponent, errorPathEncodeRequest)
4623{
4624 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304625 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304626 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4627
4628 auto rc = encode_cancel_update_component_req(
4629 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4630 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4631
4632 rc = encode_cancel_update_component_req(
4633 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4634 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4635}
4636
4637TEST(CancelUpdateComponent, testGoodDecodeResponse)
4638{
4639 uint8_t completionCode = 0;
4640 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4641 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304642 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304643 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4644 cancelUpdateComponentResponse1.data());
4645 auto rc = decode_cancel_update_component_resp(
4646 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4647 &completionCode);
4648 EXPECT_EQ(rc, PLDM_SUCCESS);
4649 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4650
4651 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4652 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304653 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304654 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4655 cancelUpdateComponentResponse2.data());
4656 rc = decode_cancel_update_component_resp(
4657 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4658 &completionCode);
4659 EXPECT_EQ(rc, PLDM_SUCCESS);
4660 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4661}
4662
4663TEST(CancelUpdateComponent, testBadDecodeResponse)
4664{
4665 uint8_t completionCode = 0;
4666 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4667 0x00, 0x00, 0x00};
4668 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304669 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304670 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4671
4672 auto rc = decode_cancel_update_component_resp(
4673 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4674 &completionCode);
4675 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4676
4677 rc = decode_cancel_update_component_resp(
4678 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4679 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4680
4681 rc = decode_cancel_update_component_resp(
4682 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4683 &completionCode);
4684 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4685}
4686
4687TEST(CancelUpdate, goodPathEncodeRequest)
4688{
4689 constexpr uint8_t instanceId = 10;
4690 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304691 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304692 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4693
4694 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4695 PLDM_CANCEL_UPDATE_REQ_BYTES);
4696 EXPECT_EQ(rc, PLDM_SUCCESS);
4697
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004698 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304699 EXPECT_EQ(request, outRequest);
4700}
4701
4702TEST(CancelUpdate, errorPathEncodeRequest)
4703{
4704 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304705 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304706 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4707
4708 auto rc =
4709 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4710 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4711
4712 rc = encode_cancel_update_req(0, requestMsg,
4713 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4714 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4715}
4716
4717TEST(CancelUpdate, goodPathDecodeResponse)
4718{
4719 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4720 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4721 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4723 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304724 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304725 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4726 uint8_t completionCode = 0;
4727 bool8_t nonFunctioningComponentIndication = 0;
4728 bitfield64_t nonFunctioningComponentBitmap{0};
4729 auto rc = decode_cancel_update_resp(
4730 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4731 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4732 EXPECT_EQ(rc, PLDM_SUCCESS);
4733 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4734 EXPECT_EQ(nonFunctioningComponentIndication,
4735 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4736 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4737 nonFunctioningComponentBitmap1);
4738
4739 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4740 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4741 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4743 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304744 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304745 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4746 rc = decode_cancel_update_resp(
4747 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4748 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4749 EXPECT_EQ(rc, PLDM_SUCCESS);
4750 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4751 EXPECT_EQ(nonFunctioningComponentIndication,
4752 PLDM_FWUP_COMPONENTS_NOT_FUNCTIONING);
4753 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4754 nonFunctioningComponentBitmap2);
4755
4756 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4757 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4758 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304759 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304760 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4761 rc = decode_cancel_update_resp(
4762 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4763 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4764 EXPECT_EQ(rc, PLDM_SUCCESS);
4765 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4766}
4767
4768TEST(CancelUpdate, errorPathDecodeResponse)
4769{
4770 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4771 0x00};
4772 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304773 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304774 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4775 uint8_t completionCode = 0;
4776 bool8_t nonFunctioningComponentIndication = 0;
4777 bitfield64_t nonFunctioningComponentBitmap{0};
4778
4779 auto rc = decode_cancel_update_resp(
4780 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4781 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4782 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4783
4784 rc = decode_cancel_update_resp(
4785 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4786 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4787 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4788
4789 rc = decode_cancel_update_resp(
4790 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4791 nullptr, &nonFunctioningComponentBitmap);
4792 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4793
4794 rc = decode_cancel_update_resp(
4795 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4796 &nonFunctioningComponentIndication, nullptr);
4797 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4798
4799 rc = decode_cancel_update_resp(
4800 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4801 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4802 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4803
4804 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4805 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4806 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304807 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304808 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4809 rc = decode_cancel_update_resp(
4810 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4811 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4812 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4813
4814 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4815 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4817 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304818 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304819 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4820 rc = decode_cancel_update_resp(
4821 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4822 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4823 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4824}
Andrew Jeffery2613c272025-03-12 14:15:41 +10304825
4826#ifdef LIBPLDM_API_TESTING
4827TEST(DecodePldmFirmwareUpdatePackage, badArguments)
4828{
4829 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
4830 pldm_package_header_information_pad hdr;
4831 struct pldm_package_iter iter;
4832 uint8_t data;
4833 int rc;
4834
4835 rc = decode_pldm_firmware_update_package(nullptr, 0, &pin, &hdr, &iter);
4836 EXPECT_EQ(rc, -EINVAL);
4837
4838 rc = decode_pldm_firmware_update_package(&data, sizeof(data), nullptr, &hdr,
4839 &iter);
4840 EXPECT_EQ(rc, -EINVAL);
4841
4842 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, nullptr,
4843 &iter);
4844 EXPECT_EQ(rc, -EINVAL);
4845
4846 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4847 nullptr);
4848 EXPECT_EQ(rc, -EINVAL);
4849}
4850#endif
4851
4852#ifdef LIBPLDM_API_TESTING
4853TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinVersion)
4854{
4855 const struct pldm_package_format_pin pin = {
4856 .meta =
4857 {
4858 .magic = 0,
4859 .version = UINT8_MAX,
4860 },
4861 .format =
4862 {
4863 .identifier = {0},
4864 .revision = 0,
4865 },
4866 };
4867
4868 pldm_package_header_information_pad hdr;
4869 struct pldm_package_iter iter;
4870 uint8_t data = 0;
4871 int rc;
4872
4873 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4874 &iter);
4875 EXPECT_EQ(rc, -ENOTSUP);
4876}
4877#endif
4878
4879#ifdef LIBPLDM_API_TESTING
4880TEST(DecodePldmFirmwareUpdatePackage, badPinRevision)
4881{
4882 const struct pldm_package_format_pin lowPin = {
4883 .meta =
4884 {
4885 .magic = 0,
4886 .version = 0,
4887 },
4888 .format =
4889 {
4890 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4891 .revision = 0,
4892 },
4893 };
4894
4895 const struct pldm_package_format_pin highPin = {
4896 .meta =
4897 {
4898 .magic = 0,
4899 .version = 0,
4900 },
4901 .format =
4902 {
4903 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4904 .revision = 3,
4905 },
4906 };
4907
4908 pldm_package_header_information_pad hdr;
4909 struct pldm_package_iter iter;
4910 uint8_t data = 0;
4911 int rc;
4912
4913 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4914 &iter);
4915 EXPECT_EQ(rc, -EINVAL);
4916
4917 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4918 &hdr, &iter);
4919 EXPECT_EQ(rc, -ENOTSUP);
4920}
4921#endif
4922
4923#ifdef LIBPLDM_API_TESTING
4924TEST(DecodePldmFirmwareUpdatePackage, badPinMagic)
4925{
4926 const struct pldm_package_format_pin lowPin = {
4927 .meta =
4928 {
4929 .magic = 0,
4930 .version = 0,
4931 },
4932 .format =
4933 {
4934 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4935 .revision = 2,
4936 },
4937 };
4938
4939 const struct pldm_package_format_pin highPin = {
4940 .meta =
4941 {
4942 .magic = UINT32_MAX,
4943 .version = 0,
4944 },
4945 .format =
4946 {
4947 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4948 .revision = 2,
4949 },
4950 };
4951
4952 pldm_package_header_information_pad hdr;
4953 struct pldm_package_iter iter;
4954 uint8_t data = 0;
4955 int rc;
4956
4957 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
4958 &iter);
4959 EXPECT_EQ(rc, -EINVAL);
4960
4961 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
4962 &hdr, &iter);
4963 EXPECT_EQ(rc, -EINVAL);
4964}
4965#endif
4966
4967#ifdef LIBPLDM_API_TESTING
4968TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinIdentifier)
4969{
4970 const struct pldm_package_format_pin pin = {
4971 .meta =
4972 {
4973 .magic =
4974 LIBPLDM_SIZEAT(struct pldm__package_header_information,
4975 package) +
4976 LIBPLDM_SIZEAT(
4977 struct pldm_package_firmware_device_id_record,
4978 firmware_device_package_data) +
4979 LIBPLDM_SIZEAT(struct pldm_descriptor, descriptor_data) +
4980 LIBPLDM_SIZEAT(
4981 struct pldm_package_downstream_device_id_record,
4982 package_data) +
4983 LIBPLDM_SIZEAT(
4984 struct pldm_package_component_image_information,
4985 component_version_string) +
4986 LIBPLDM_SIZEAT(struct pldm_package_iter, infos),
4987 .version = 0,
4988 },
4989 .format =
4990 {
4991 .identifier = {0},
4992 .revision = PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR02H,
4993 },
4994 };
4995
4996 pldm_package_header_information_pad hdr;
4997 struct pldm_package_iter iter;
4998 uint8_t data = 0;
4999 int rc;
5000
5001 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
5002 &iter);
5003 EXPECT_EQ(rc, -ENOTSUP);
5004}
5005#endif
5006
5007#ifdef LIBPLDM_API_TESTING
5008TEST(DecodePldmFirmwareUpdatePackage, oldConsumer)
5009{
5010 /* Package format revision 2 header */
5011 const std::array<uint8_t, 150> package{
5012 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5013 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5014 0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5015 0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5016 };
5017
5018 /* Package format revision 1 consumer */
5019 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5020
5021 pldm_package_header_information_pad hdr;
5022 struct pldm_package_iter iter;
5023 int rc;
5024
5025 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5026 &pin, &hdr, &iter);
5027 EXPECT_EQ(rc, -ENOTSUP);
5028}
5029#endif
5030
5031#ifdef LIBPLDM_API_TESTING
5032TEST(DecodePldmFirmwareUpdatePackage, v1h1fd1fdd1cii)
5033{
5034 const std::array<uint8_t, 102> package{
5035 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5036 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5037 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5038 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5039
5040 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5041 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c,
5042 0x01, 0x00, 0x00,
5043
5044 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5045 0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5046 0x01, 0x04, 'v', '0', '.', '2', 0x00, 0x00, 0x00, 0x00,
5047
5048 0xb5, 0x3f, 0xf6, 0x6a,
5049
5050 0x5a,
5051 };
5052
5053 struct pldm_package_downstream_device_id_record ddrec;
5054 struct pldm_package_component_image_information info;
5055 struct pldm_package_firmware_device_id_record fdrec;
5056 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5057 pldm_package_header_information_pad hdr;
5058 struct pldm_package_iter iter;
5059 int nr_fdrec_desc = 0;
5060 int nr_ddrec_desc = 0;
5061 int nr_fdrec = 0;
5062 int nr_ddrec = 0;
5063 int nr_infos = 0;
5064 int rc;
5065
5066 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5067 &pin, &hdr, &iter);
5068 ASSERT_EQ(rc, 0);
5069
5070 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5071 hdr.package_header_identifier,
5072 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5073 0);
5074 EXPECT_EQ(hdr.package_header_format_revision, 1);
5075
5076 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5077 0x16, 0x03, 0x00, 0x00, 0x00,
5078 0x00, 0x76, 0x02};
5079 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5080 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5081 timestamp.size()),
5082 0);
5083
5084 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5085 EXPECT_EQ(hdr.package_version_string_type, 1);
5086 ASSERT_EQ(hdr.package_version_string.length, 4);
5087 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5088 hdr.package_version_string.length),
5089 0);
5090 EXPECT_NE(hdr.areas.ptr, nullptr);
5091 EXPECT_NE(hdr.areas.length, 0);
5092 EXPECT_NE(hdr.package.ptr, nullptr);
5093 EXPECT_NE(hdr.package.length, 0);
5094
5095 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5096 {
5097 struct pldm_descriptor desc;
5098
5099 EXPECT_EQ(fdrec.descriptor_count, 1);
5100 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5101 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5102 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5103 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5104 fdrec.component_image_set_version_string.length),
5105 0);
5106 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5107 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5108 EXPECT_NE(fdrec.record_descriptors.length, 0);
5109 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5110 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5111
5112 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5113 desc, rc)
5114 {
5115 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5116
5117 EXPECT_EQ(desc.descriptor_type, 1);
5118 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5119 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5120 sizeof(iana_pen_dmtf)),
5121 0);
5122
5123 nr_fdrec_desc++;
5124 }
5125 ASSERT_EQ(rc, 0);
5126
5127 nr_fdrec++;
5128 }
5129 ASSERT_EQ(rc, 0);
5130
5131 EXPECT_EQ(nr_fdrec, 1);
5132 EXPECT_EQ(nr_fdrec_desc, 1);
5133
5134 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5135 {
5136 struct pldm_descriptor desc;
5137
5138 EXPECT_EQ(ddrec.descriptor_count, 1);
5139 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5140 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5141 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5142 EXPECT_EQ(
5143 memcmp("v1.0",
5144 ddrec.self_contained_activation_min_version_string.ptr,
5145 ddrec.self_contained_activation_min_version_string.length),
5146 0);
5147 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5148 0);
5149 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5150 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5151 EXPECT_NE(ddrec.record_descriptors.length, 0);
5152 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5153 EXPECT_EQ(ddrec.package_data.length, 0);
5154
5155 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5156 desc, rc)
5157 {
5158 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5159
5160 EXPECT_EQ(desc.descriptor_type, 1);
5161 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5162 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5163 sizeof(iana_pen_dmtf)),
5164 0);
5165
5166 nr_ddrec_desc++;
5167 }
5168 ASSERT_EQ(rc, 0);
5169
5170 nr_ddrec++;
5171 }
5172 ASSERT_EQ(rc, 0);
5173
5174 EXPECT_EQ(nr_ddrec, 0);
5175 EXPECT_EQ(nr_ddrec_desc, 0);
5176
5177 static const pldm_package_component_image_information expected_info{
Carter Chenf72cf6f2025-06-24 15:34:49 +08005178 0x000a, 0x0000, 0xffffffff, {0}, {1},
5179 {nullptr, 1}, 0x01, {nullptr, 0}, {nullptr, 0}};
Andrew Jeffery2613c272025-03-12 14:15:41 +10305180
5181 foreach_pldm_package_component_image_information(iter, info, rc)
5182 {
5183 EXPECT_EQ(info.component_classification,
5184 expected_info.component_classification);
5185 EXPECT_EQ(info.component_identifier,
5186 expected_info.component_identifier);
5187 EXPECT_EQ(info.component_comparison_stamp,
5188 expected_info.component_comparison_stamp);
5189 EXPECT_EQ(info.component_options.value,
5190 expected_info.component_options.value);
5191 EXPECT_EQ(info.requested_component_activation_method.value,
5192 expected_info.requested_component_activation_method.value);
5193 EXPECT_NE(nullptr, info.component_image.ptr);
5194 EXPECT_EQ(info.component_image.length,
5195 expected_info.component_image.length);
5196 EXPECT_EQ(info.component_version_string_type,
5197 expected_info.component_version_string_type);
5198 ASSERT_EQ(info.component_version_string.length, 4);
5199 EXPECT_EQ(memcmp("v0.2", info.component_version_string.ptr,
5200 info.component_version_string.length),
5201 0);
5202
5203 nr_infos++;
5204 }
5205 ASSERT_EQ(rc, 0);
5206
5207 EXPECT_EQ(nr_infos, 1);
5208}
5209#endif
5210
5211#ifdef LIBPLDM_API_TESTING
5212TEST(DecodePldmFirmwareUpdatePackage, v2h1fd1fdd1dd1ddd2cii)
5213{
5214 const std::array<uint8_t, 150> package{
5215 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5216 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5217 0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5218 0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5219
5220 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5221 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
5222 0x00, 0x9c, 0x01, 0x00, 0x00,
5223
5224 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5225 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
5226 0x00, 0x9c, 0x01, 0x00, 0x00,
5227
5228 0x02, 0x00,
5229
5230 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5231 0x01, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5232 0x01, 0x04, 'v', '0', '.', '2',
5233
5234 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5235 0x01, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5236 0x01, 0x04, 'v', '2', '.', '0',
5237
5238 0xd3, 0x5c, 0x1c, 0x8a,
5239
5240 0x5a,
5241
5242 0xa5,
5243 };
5244 struct pldm_package_downstream_device_id_record ddrec;
5245 struct pldm_package_component_image_information info;
5246 struct pldm_package_firmware_device_id_record fdrec;
5247 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5248 pldm_package_header_information_pad hdr;
5249 struct pldm_package_iter iter;
5250 int nr_fdrec_desc = 0;
5251 int nr_ddrec_desc = 0;
5252 int nr_fdrec = 0;
5253 int nr_ddrec = 0;
5254 int nr_infos = 0;
5255 int rc;
5256
5257 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5258 &pin, &hdr, &iter);
5259 ASSERT_EQ(rc, 0);
5260
5261 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.data(),
5262 hdr.package_header_identifier,
5263 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.size()),
5264 0);
5265 EXPECT_EQ(hdr.package_header_format_revision, 2);
5266
5267 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5268 0x16, 0x03, 0x00, 0x00, 0x00,
5269 0x00, 0x76, 0x02};
5270 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5271 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5272 timestamp.size()),
5273 0);
5274
5275 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5276 EXPECT_EQ(hdr.package_version_string_type, 1);
5277 ASSERT_EQ(hdr.package_version_string.length, 4);
5278 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5279 hdr.package_version_string.length),
5280 0);
5281 EXPECT_NE(hdr.areas.ptr, nullptr);
5282 EXPECT_NE(hdr.areas.length, 0);
5283 EXPECT_NE(hdr.package.ptr, nullptr);
5284 EXPECT_NE(hdr.package.length, 0);
5285
5286 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5287 {
5288 struct pldm_descriptor desc;
5289
5290 EXPECT_EQ(fdrec.descriptor_count, 1);
5291 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5292 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5293 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5294 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5295 fdrec.component_image_set_version_string.length),
5296 0);
5297 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5298 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5299 EXPECT_NE(fdrec.record_descriptors.length, 0);
5300 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5301 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5302
5303 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5304 desc, rc)
5305 {
5306 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5307
5308 EXPECT_EQ(desc.descriptor_type, 1);
5309 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5310 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5311 sizeof(iana_pen_dmtf)),
5312 0);
5313
5314 nr_fdrec_desc++;
5315 }
5316 ASSERT_EQ(rc, 0);
5317
5318 nr_fdrec++;
5319 }
5320 ASSERT_EQ(rc, 0);
5321
5322 EXPECT_EQ(nr_fdrec, 1);
5323 EXPECT_EQ(nr_fdrec_desc, 1);
5324
5325 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5326 {
5327 struct pldm_descriptor desc;
5328
5329 EXPECT_EQ(ddrec.descriptor_count, 1);
5330 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5331 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5332 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5333 EXPECT_EQ(
5334 memcmp("v1.0",
5335 ddrec.self_contained_activation_min_version_string.ptr,
5336 ddrec.self_contained_activation_min_version_string.length),
5337 0);
5338 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5339 0);
5340 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5341 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5342 EXPECT_NE(ddrec.record_descriptors.length, 0);
5343 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5344 EXPECT_EQ(ddrec.package_data.length, 0);
5345
5346 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5347 desc, rc)
5348 {
5349 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5350
5351 EXPECT_EQ(desc.descriptor_type, 1);
5352 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5353 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5354 sizeof(iana_pen_dmtf)),
5355 0);
5356
5357 nr_ddrec_desc++;
5358 }
5359 ASSERT_EQ(rc, 0);
5360
5361 nr_ddrec++;
5362 }
5363 ASSERT_EQ(rc, 0);
5364
5365 EXPECT_EQ(nr_ddrec, 1);
5366 EXPECT_EQ(nr_ddrec_desc, 1);
5367
5368 static const std::array<const char*, 2> component_versions = {
5369 "v0.2",
5370 "v2.0",
5371 };
5372 static const std::array<pldm_package_component_image_information, 2>
5373 expected_infos{{{0x000a,
5374 0x0000,
5375 0xffffffff,
5376 {0},
5377 {1},
5378 {nullptr, 1},
5379 0x01,
Carter Chenf72cf6f2025-06-24 15:34:49 +08005380 {nullptr, 0},
Andrew Jeffery2613c272025-03-12 14:15:41 +10305381 {nullptr, 0}},
5382 {0x000a,
5383 0x0000,
5384 0xffffffff,
5385 {0},
5386 {1},
5387 {nullptr, 1},
5388 0x01,
Carter Chenf72cf6f2025-06-24 15:34:49 +08005389 {nullptr, 0},
Andrew Jeffery2613c272025-03-12 14:15:41 +10305390 {nullptr, 0}}}};
5391 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5392
5393 foreach_pldm_package_component_image_information(iter, info, rc)
5394 {
5395 const struct pldm_package_component_image_information* expected;
5396 const char* version;
5397 uint8_t image;
5398
5399 expected = &expected_infos.at(nr_infos);
5400 version = component_versions.at(nr_infos);
5401 image = expected_images.at(nr_infos);
5402
5403 EXPECT_EQ(info.component_classification,
5404 expected->component_classification);
5405 EXPECT_EQ(info.component_identifier, expected->component_identifier);
5406 EXPECT_EQ(info.component_comparison_stamp,
5407 expected->component_comparison_stamp);
5408 EXPECT_EQ(info.component_options.value,
5409 expected->component_options.value);
5410 EXPECT_EQ(info.requested_component_activation_method.value,
5411 expected->requested_component_activation_method.value);
5412 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5413 EXPECT_EQ(info.component_image.length,
5414 expected->component_image.length);
5415 EXPECT_EQ(*info.component_image.ptr, image);
5416 EXPECT_EQ(info.component_version_string_type,
5417 expected->component_version_string_type);
5418 ASSERT_EQ(info.component_version_string.length, 4);
5419 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5420 info.component_version_string.length),
5421 0);
5422
5423 nr_infos++;
5424 }
5425 ASSERT_EQ(rc, 0);
5426
5427 EXPECT_EQ(nr_infos, 2);
5428}
5429#endif
Carter Chenf72cf6f2025-06-24 15:34:49 +08005430
5431#ifdef LIBPLDM_API_TESTING
5432TEST(DecodePldmFirmwareUpdatePackage, v3h1fd1fdd1dd1ddd2cii)
5433{
5434 const std::array<uint8_t, 166> package{
5435 0x31, 0x19, 0xce, 0x2f, 0xe8, 0x0a, 0x4a, 0x99, 0xaf, 0x6d, 0x46, 0xf8,
5436 0xb1, 0x21, 0xf6, 0xbf, 0x03, 0xA4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5437 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5438 't', 'e', 's', 't',
5439
5440 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5441 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5442 0x00,
5443
5444 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5445 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5446 0x00,
5447
5448 0x02, 0x00,
5449
5450 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5451 0xA4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '0',
5452 '.', '2', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5453
5454 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5455 0xA5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '2',
5456 '.', '0', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5457
5458 0xed, 0x9d, 0x97, 0x7a,
5459
5460 0x5a,
5461
5462 0xa5,
5463
5464 };
5465
5466 struct pldm_package_downstream_device_id_record ddrec;
5467 struct pldm_package_component_image_information info;
5468 struct pldm_package_firmware_device_id_record fdrec;
5469 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR03H(pin);
5470 pldm_package_header_information_pad hdr;
5471 struct pldm_package_iter iter;
5472 int nr_fdrec_desc = 0;
5473 int nr_ddrec_desc = 0;
5474 int nr_fdrec = 0;
5475 int nr_ddrec = 0;
5476 int nr_infos = 0;
5477 int rc;
5478
5479 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5480 &pin, &hdr, &iter);
5481 ASSERT_EQ(rc, 0);
5482
5483 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.data(),
5484 hdr.package_header_identifier,
5485 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.size()),
5486 0);
5487 EXPECT_EQ(hdr.package_header_format_revision, 3);
5488
5489 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5490 0x16, 0x03, 0x00, 0x00, 0x00,
5491 0x00, 0x76, 0x02};
5492 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5493 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5494 timestamp.size()),
5495 0);
5496
5497 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5498 EXPECT_EQ(hdr.package_version_string_type, 1);
5499 ASSERT_EQ(hdr.package_version_string.length, 4);
5500 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5501 hdr.package_version_string.length),
5502 0);
5503 EXPECT_NE(hdr.areas.ptr, nullptr);
5504 EXPECT_NE(hdr.areas.length, 0);
5505 EXPECT_NE(hdr.package.ptr, nullptr);
5506 EXPECT_NE(hdr.package.length, 0);
5507
5508 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5509 {
5510 struct pldm_descriptor desc;
5511
5512 EXPECT_EQ(fdrec.descriptor_count, 1);
5513 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5514 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5515 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5516 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5517 fdrec.component_image_set_version_string.length),
5518 0);
5519 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5520 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5521 EXPECT_NE(fdrec.record_descriptors.length, 0);
5522 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5523 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5524
5525 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5526 desc, rc)
5527 {
5528 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5529
5530 EXPECT_EQ(desc.descriptor_type, 1);
5531 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5532 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5533 sizeof(iana_pen_dmtf)),
5534 0);
5535
5536 nr_fdrec_desc++;
5537 }
5538 ASSERT_EQ(rc, 0);
5539
5540 nr_fdrec++;
5541 }
5542 ASSERT_EQ(rc, 0);
5543
5544 EXPECT_EQ(nr_fdrec, 1);
5545 EXPECT_EQ(nr_fdrec_desc, 1);
5546
5547 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5548 {
5549 struct pldm_descriptor desc;
5550
5551 EXPECT_EQ(ddrec.descriptor_count, 1);
5552 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5553 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5554 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5555 EXPECT_EQ(
5556 memcmp("v1.0",
5557 ddrec.self_contained_activation_min_version_string.ptr,
5558 ddrec.self_contained_activation_min_version_string.length),
5559 0);
5560 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5561 0);
5562 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5563 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5564 EXPECT_NE(ddrec.record_descriptors.length, 0);
5565 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5566 EXPECT_EQ(ddrec.package_data.length, 0);
5567
5568 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5569 desc, rc)
5570 {
5571 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5572
5573 EXPECT_EQ(desc.descriptor_type, 1);
5574 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5575 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5576 sizeof(iana_pen_dmtf)),
5577 0);
5578
5579 nr_ddrec_desc++;
5580 }
5581 ASSERT_EQ(rc, 0);
5582
5583 nr_ddrec++;
5584 }
5585 ASSERT_EQ(rc, 0);
5586
5587 EXPECT_EQ(nr_ddrec, 1);
5588 EXPECT_EQ(nr_ddrec_desc, 1);
5589
5590 static const std::array<const char*, 2> component_versions = {
5591 "v0.2",
5592 "v2.0",
5593 };
5594
5595 static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
5596 0x78};
5597
5598 static const std::array<pldm_package_component_image_information, 2>
5599 expected_infos{
5600 {{0x000a,
5601 0x0000,
5602 0xffffffff,
5603 {0},
5604 {1},
5605 {nullptr, 1},
5606 0x01,
5607 {nullptr, 0},
5608 {expected_opaque_data.data(), expected_opaque_data.size()}},
5609 {0x000a,
5610 0x0000,
5611 0xffffffff,
5612 {0},
5613 {1},
5614 {nullptr, 1},
5615 0x01,
5616 {nullptr, 0},
5617 {expected_opaque_data.data(), expected_opaque_data.size()}}}};
5618 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5619
5620 foreach_pldm_package_component_image_information(iter, info, rc)
5621 {
5622 const struct pldm_package_component_image_information* expected;
5623 const char* version;
5624 uint8_t image;
5625
5626 expected = &expected_infos.at(nr_infos);
5627 version = component_versions.at(nr_infos);
5628 image = expected_images.at(nr_infos);
5629
5630 EXPECT_EQ(info.component_classification,
5631 expected->component_classification);
5632 EXPECT_EQ(info.component_identifier, expected->component_identifier);
5633 EXPECT_EQ(info.component_comparison_stamp,
5634 expected->component_comparison_stamp);
5635 EXPECT_EQ(info.component_options.value,
5636 expected->component_options.value);
5637 EXPECT_EQ(info.requested_component_activation_method.value,
5638 expected->requested_component_activation_method.value);
5639 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5640 EXPECT_EQ(info.component_image.length,
5641 expected->component_image.length);
5642 EXPECT_EQ(*info.component_image.ptr, image);
5643 EXPECT_EQ(info.component_version_string_type,
5644 expected->component_version_string_type);
5645 ASSERT_EQ(info.component_version_string.length, 4);
5646 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5647 info.component_version_string.length),
5648 0);
5649 EXPECT_EQ(info.component_opaque_data.length,
5650 expected->component_opaque_data.length);
5651 EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
5652 expected->component_opaque_data.ptr,
5653 expected->component_opaque_data.length),
5654 0);
5655 nr_infos++;
5656 }
5657 ASSERT_EQ(rc, 0);
5658
5659 EXPECT_EQ(nr_infos, 2);
5660}
Carter Chen01782742025-06-25 13:53:50 +08005661#endif
5662
5663#ifdef LIBPLDM_API_TESTING
5664TEST(DecodePldmFirmwareUpdatePackage, v4h1fd1fdd1dd1ddd2cii)
5665{
5666 const std::array<uint8_t, 182> package{
5667 0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
5668 0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5669 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5670 't', 'e', 's', 't',
5671
5672 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5673 0x02, 0x00, 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
5674 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
5675
5676 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5677 0x02, 0x00, 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
5678 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
5679
5680 0x02, 0x00,
5681
5682 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5683 0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '0',
5684 '.', '2', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5685
5686 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5687 0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '2',
5688 '.', '0', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5689
5690 0xf7, 0xf7, 0xfd, 0x79,
5691
5692 0x46, 0xf0, 0x31, 0xa7,
5693
5694 0x5a,
5695
5696 0xa5,
5697
5698 };
5699
5700 struct pldm_package_downstream_device_id_record ddrec;
5701 struct pldm_package_component_image_information info;
5702 struct pldm_package_firmware_device_id_record fdrec;
5703 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
5704 pldm_package_header_information_pad hdr;
5705 struct pldm_package_iter iter;
5706 int nr_fdrec_desc = 0;
5707 int nr_ddrec_desc = 0;
5708 int nr_fdrec = 0;
5709 int nr_ddrec = 0;
5710 int nr_infos = 0;
5711 int rc;
5712
5713 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
5714 &pin, &hdr, &iter);
5715 ASSERT_EQ(rc, 0);
5716
5717 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3.data(),
5718 hdr.package_header_identifier,
5719 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3.size()),
5720 0);
5721 EXPECT_EQ(hdr.package_header_format_revision, 4);
5722
5723 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5724 0x16, 0x03, 0x00, 0x00, 0x00,
5725 0x00, 0x76, 0x02};
5726 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5727 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5728 timestamp.size()),
5729 0);
5730
5731 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5732 EXPECT_EQ(hdr.package_version_string_type, 1);
5733 ASSERT_EQ(hdr.package_version_string.length, 4);
5734 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5735 hdr.package_version_string.length),
5736 0);
5737 EXPECT_NE(hdr.areas.ptr, nullptr);
5738 EXPECT_NE(hdr.areas.length, 0);
5739 EXPECT_NE(hdr.package.ptr, nullptr);
5740 EXPECT_NE(hdr.package.length, 0);
5741
5742 foreach_pldm_package_firmware_device_id_record(iter, fdrec, rc)
5743 {
5744 struct pldm_descriptor desc;
5745
5746 static const uint8_t expected_reference_manifest_data[] = {0x87, 0x65};
5747
5748 EXPECT_EQ(fdrec.descriptor_count, 1);
5749 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5750 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5751 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5752 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5753 fdrec.component_image_set_version_string.length),
5754 0);
5755 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5756 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5757 EXPECT_NE(fdrec.record_descriptors.length, 0);
5758 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5759 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5760 EXPECT_EQ(fdrec.reference_manifest_data.length,
5761 sizeof(expected_reference_manifest_data));
5762 EXPECT_EQ(memcmp(fdrec.reference_manifest_data.ptr,
5763 expected_reference_manifest_data,
5764 sizeof(expected_reference_manifest_data)),
5765 0);
5766 foreach_pldm_package_firmware_device_id_record_descriptor(iter, fdrec,
5767 desc, rc)
5768 {
5769 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5770
5771 EXPECT_EQ(desc.descriptor_type, 1);
5772 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5773 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5774 sizeof(iana_pen_dmtf)),
5775 0);
5776
5777 nr_fdrec_desc++;
5778 }
5779 ASSERT_EQ(rc, 0);
5780
5781 nr_fdrec++;
5782 }
5783 ASSERT_EQ(rc, 0);
5784
5785 EXPECT_EQ(nr_fdrec, 1);
5786 EXPECT_EQ(nr_fdrec_desc, 1);
5787
5788 foreach_pldm_package_downstream_device_id_record(iter, ddrec, rc)
5789 {
5790 struct pldm_descriptor desc;
5791
5792 static const uint8_t expected_reference_manifest_data[] = {0x87, 0x65};
5793
5794 EXPECT_EQ(ddrec.descriptor_count, 1);
5795 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5796 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5797 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5798 EXPECT_EQ(
5799 memcmp("v1.0",
5800 ddrec.self_contained_activation_min_version_string.ptr,
5801 ddrec.self_contained_activation_min_version_string.length),
5802 0);
5803 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5804 0);
5805 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5806 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5807 EXPECT_NE(ddrec.record_descriptors.length, 0);
5808 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5809 EXPECT_EQ(ddrec.package_data.length, 0);
5810 EXPECT_EQ(fdrec.reference_manifest_data.length,
5811 sizeof(expected_reference_manifest_data));
5812 EXPECT_EQ(memcmp(fdrec.reference_manifest_data.ptr,
5813 expected_reference_manifest_data,
5814 sizeof(expected_reference_manifest_data)),
5815 0);
5816
5817 foreach_pldm_package_downstream_device_id_record_descriptor(iter, ddrec,
5818 desc, rc)
5819 {
5820 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5821
5822 EXPECT_EQ(desc.descriptor_type, 1);
5823 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5824 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5825 sizeof(iana_pen_dmtf)),
5826 0);
5827
5828 nr_ddrec_desc++;
5829 }
5830 ASSERT_EQ(rc, 0);
5831
5832 nr_ddrec++;
5833 }
5834 ASSERT_EQ(rc, 0);
5835
5836 EXPECT_EQ(nr_ddrec, 1);
5837 EXPECT_EQ(nr_ddrec_desc, 1);
5838
5839 static const std::array<const char*, 2> component_versions = {
5840 "v0.2",
5841 "v2.0",
5842 };
5843
5844 static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
5845 0x78};
5846
5847 static const std::array<pldm_package_component_image_information, 2>
5848 expected_infos{
5849 {{0x000a,
5850 0x0000,
5851 0xffffffff,
5852 {0},
5853 {1},
5854 {nullptr, 1},
5855 0x01,
5856 {nullptr, 0},
5857 {expected_opaque_data.data(), expected_opaque_data.size()}},
5858 {0x000a,
5859 0x0000,
5860 0xffffffff,
5861 {0},
5862 {1},
5863 {nullptr, 1},
5864 0x01,
5865 {nullptr, 0},
5866 {expected_opaque_data.data(), expected_opaque_data.size()}}}};
5867 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5868
5869 foreach_pldm_package_component_image_information(iter, info, rc)
5870 {
5871 const struct pldm_package_component_image_information* expected;
5872 const char* version;
5873 uint8_t image;
5874
5875 expected = &expected_infos.at(nr_infos);
5876 version = component_versions.at(nr_infos);
5877 image = expected_images.at(nr_infos);
5878
5879 EXPECT_EQ(info.component_classification,
5880 expected->component_classification);
5881 EXPECT_EQ(info.component_identifier, expected->component_identifier);
5882 EXPECT_EQ(info.component_comparison_stamp,
5883 expected->component_comparison_stamp);
5884 EXPECT_EQ(info.component_options.value,
5885 expected->component_options.value);
5886 EXPECT_EQ(info.requested_component_activation_method.value,
5887 expected->requested_component_activation_method.value);
5888 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5889 EXPECT_EQ(info.component_image.length,
5890 expected->component_image.length);
5891 EXPECT_EQ(*info.component_image.ptr, image);
5892 EXPECT_EQ(info.component_version_string_type,
5893 expected->component_version_string_type);
5894 ASSERT_EQ(info.component_version_string.length, 4);
5895 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5896 info.component_version_string.length),
5897 0);
5898 EXPECT_EQ(info.component_opaque_data.length,
5899 expected->component_opaque_data.length);
5900 EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
5901 expected->component_opaque_data.ptr,
5902 expected->component_opaque_data.length),
5903 0);
5904
5905 nr_infos++;
5906 }
5907 ASSERT_EQ(rc, 0);
5908
5909 EXPECT_EQ(nr_infos, 2);
5910}
Carter Chenf72cf6f2025-06-24 15:34:49 +08005911#endif