blob: 53ff4fffb25e40810ed766293cfb408075b5c0fd [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;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00004831 struct pldm_package pkg{};
Andrew Jeffery2613c272025-03-12 14:15:41 +10304832 uint8_t data;
4833 int rc;
4834
Andrew Jeffery72442de2025-08-12 08:47:42 +00004835 rc = decode_pldm_firmware_update_package(nullptr, 0, &pin, &hdr, &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304836 EXPECT_EQ(rc, -EINVAL);
4837
4838 rc = decode_pldm_firmware_update_package(&data, sizeof(data), nullptr, &hdr,
Andrew Jeffery72442de2025-08-12 08:47:42 +00004839 &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304840 EXPECT_EQ(rc, -EINVAL);
4841
4842 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, nullptr,
Andrew Jeffery72442de2025-08-12 08:47:42 +00004843 &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304844 EXPECT_EQ(rc, -EINVAL);
4845
4846 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
Andrew Jeffery72442de2025-08-12 08:47:42 +00004847 nullptr, 0);
4848 EXPECT_EQ(rc, -EINVAL);
4849
4850 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
4851 &pkg, UINT32_MAX);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304852 EXPECT_EQ(rc, -EINVAL);
4853}
4854#endif
4855
4856#ifdef LIBPLDM_API_TESTING
4857TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinVersion)
4858{
4859 const struct pldm_package_format_pin pin = {
4860 .meta =
4861 {
4862 .magic = 0,
4863 .version = UINT8_MAX,
4864 },
4865 .format =
4866 {
4867 .identifier = {0},
4868 .revision = 0,
4869 },
4870 };
4871
4872 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00004873 struct pldm_package pkg{};
Andrew Jeffery2613c272025-03-12 14:15:41 +10304874 uint8_t data = 0;
4875 int rc;
4876
4877 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
Andrew Jeffery72442de2025-08-12 08:47:42 +00004878 &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304879 EXPECT_EQ(rc, -ENOTSUP);
4880}
4881#endif
4882
4883#ifdef LIBPLDM_API_TESTING
4884TEST(DecodePldmFirmwareUpdatePackage, badPinRevision)
4885{
4886 const struct pldm_package_format_pin lowPin = {
4887 .meta =
4888 {
4889 .magic = 0,
4890 .version = 0,
4891 },
4892 .format =
4893 {
4894 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4895 .revision = 0,
4896 },
4897 };
4898
4899 const struct pldm_package_format_pin highPin = {
4900 .meta =
4901 {
4902 .magic = 0,
4903 .version = 0,
4904 },
4905 .format =
4906 {
4907 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4908 .revision = 3,
4909 },
4910 };
4911
4912 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00004913 struct pldm_package pkg{};
Andrew Jeffery2613c272025-03-12 14:15:41 +10304914 uint8_t data = 0;
4915 int rc;
4916
4917 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
Andrew Jeffery72442de2025-08-12 08:47:42 +00004918 &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304919 EXPECT_EQ(rc, -EINVAL);
4920
4921 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
Andrew Jeffery72442de2025-08-12 08:47:42 +00004922 &hdr, &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304923 EXPECT_EQ(rc, -ENOTSUP);
4924}
4925#endif
4926
4927#ifdef LIBPLDM_API_TESTING
4928TEST(DecodePldmFirmwareUpdatePackage, badPinMagic)
4929{
4930 const struct pldm_package_format_pin lowPin = {
4931 .meta =
4932 {
4933 .magic = 0,
4934 .version = 0,
4935 },
4936 .format =
4937 {
4938 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4939 .revision = 2,
4940 },
4941 };
4942
4943 const struct pldm_package_format_pin highPin = {
4944 .meta =
4945 {
4946 .magic = UINT32_MAX,
4947 .version = 0,
4948 },
4949 .format =
4950 {
4951 .identifier = PLDM_PACKAGE_HEADER_IDENTIFIER_V1_1,
4952 .revision = 2,
4953 },
4954 };
4955
4956 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00004957 struct pldm_package pkg{};
Andrew Jeffery2613c272025-03-12 14:15:41 +10304958 uint8_t data = 0;
4959 int rc;
4960
4961 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &lowPin, &hdr,
Andrew Jeffery72442de2025-08-12 08:47:42 +00004962 &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304963 EXPECT_EQ(rc, -EINVAL);
4964
4965 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &highPin,
Andrew Jeffery72442de2025-08-12 08:47:42 +00004966 &hdr, &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10304967 EXPECT_EQ(rc, -EINVAL);
4968}
4969#endif
4970
4971#ifdef LIBPLDM_API_TESTING
4972TEST(DecodePldmFirmwareUpdatePackage, unsupportedPinIdentifier)
4973{
4974 const struct pldm_package_format_pin pin = {
4975 .meta =
4976 {
4977 .magic =
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00004978 LIBPLDM_SIZEAT(struct pldm_package, iter) +
Andrew Jeffery2613c272025-03-12 14:15:41 +10304979 LIBPLDM_SIZEAT(struct pldm__package_header_information,
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00004980 package_version_string) +
Andrew Jeffery2613c272025-03-12 14:15:41 +10304981 LIBPLDM_SIZEAT(
4982 struct pldm_package_firmware_device_id_record,
4983 firmware_device_package_data) +
4984 LIBPLDM_SIZEAT(struct pldm_descriptor, descriptor_data) +
4985 LIBPLDM_SIZEAT(
4986 struct pldm_package_downstream_device_id_record,
4987 package_data) +
4988 LIBPLDM_SIZEAT(
4989 struct pldm_package_component_image_information,
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00004990 component_version_string),
Andrew Jeffery2613c272025-03-12 14:15:41 +10304991 .version = 0,
4992 },
4993 .format =
4994 {
4995 .identifier = {0},
4996 .revision = PLDM_PACKAGE_HEADER_FORMAT_REVISION_FR02H,
4997 },
4998 };
4999
5000 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005001 struct pldm_package pkg{};
Andrew Jeffery2613c272025-03-12 14:15:41 +10305002 uint8_t data = 0;
5003 int rc;
5004
5005 rc = decode_pldm_firmware_update_package(&data, sizeof(data), &pin, &hdr,
Andrew Jeffery72442de2025-08-12 08:47:42 +00005006 &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10305007 EXPECT_EQ(rc, -ENOTSUP);
5008}
5009#endif
5010
5011#ifdef LIBPLDM_API_TESTING
5012TEST(DecodePldmFirmwareUpdatePackage, oldConsumer)
5013{
5014 /* Package format revision 2 header */
5015 const std::array<uint8_t, 150> package{
5016 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5017 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5018 0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5019 0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5020 };
5021
5022 /* Package format revision 1 consumer */
5023 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5024
5025 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005026 struct pldm_package pkg{};
Andrew Jeffery2613c272025-03-12 14:15:41 +10305027 int rc;
5028
5029 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00005030 &pin, &hdr, &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10305031 EXPECT_EQ(rc, -ENOTSUP);
5032}
5033#endif
5034
5035#ifdef LIBPLDM_API_TESTING
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005036TEST(DecodePldmFirmwareUpdatePackage, p1v1h1fd1cii)
5037{
5038 const std::array<uint8_t, 102> package{
5039 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5040 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5041 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5042 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5043
5044 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5045 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c,
5046 0x01, 0x00, 0x00,
5047
5048 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5049 0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5050 0x01, 0x04, 'v', '0', '.', '2', 0x00, 0x00, 0x00, 0x00,
5051
5052 0xb5, 0x3f, 0xf6, 0x6a,
5053
5054 0x5a,
5055 };
5056
5057 struct pldm_package_component_image_information info;
5058 struct pldm_package_firmware_device_id_record fdrec;
5059 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5060 pldm_package_header_information_pad hdr;
5061 struct pldm_package pkg{};
5062 int nr_fdrec_desc = 0;
5063 int nr_fdrec = 0;
5064 int nr_infos = 0;
5065 int rc;
5066
5067 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00005068 &pin, &hdr, &pkg, 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005069 ASSERT_EQ(rc, 0);
5070
5071 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5072 hdr.package_header_identifier,
5073 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5074 0);
5075 EXPECT_EQ(hdr.package_header_format_revision, 1);
5076
5077 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5078 0x16, 0x03, 0x00, 0x00, 0x00,
5079 0x00, 0x76, 0x02};
5080 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5081 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5082 timestamp.size()),
5083 0);
5084
5085 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5086 EXPECT_EQ(hdr.package_version_string_type, 1);
5087 ASSERT_EQ(hdr.package_version_string.length, 4);
5088 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5089 hdr.package_version_string.length),
5090 0);
5091 EXPECT_NE(pkg.areas.ptr, nullptr);
5092 EXPECT_NE(pkg.areas.length, 0);
5093 EXPECT_NE(pkg.package.ptr, nullptr);
5094 EXPECT_NE(pkg.package.length, 0);
5095
5096 foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
5097 {
5098 struct pldm_descriptor desc;
5099
5100 EXPECT_EQ(fdrec.descriptor_count, 1);
5101 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5102 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5103 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5104 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5105 fdrec.component_image_set_version_string.length),
5106 0);
5107 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5108 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5109 EXPECT_NE(fdrec.record_descriptors.length, 0);
5110 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5111 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5112
5113 foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
5114 desc, rc)
5115 {
5116 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5117
5118 EXPECT_EQ(desc.descriptor_type, 1);
5119 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5120 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5121 sizeof(iana_pen_dmtf)),
5122 0);
5123
5124 nr_fdrec_desc++;
5125 }
5126 ASSERT_EQ(rc, 0);
5127
5128 nr_fdrec++;
5129 }
5130 ASSERT_EQ(rc, 0);
5131
5132 EXPECT_EQ(nr_fdrec, 1);
5133 EXPECT_EQ(nr_fdrec_desc, 1);
5134
5135 static const pldm_package_component_image_information expected_info{
5136 0x000a, 0x0000, 0xffffffff, {0}, {1},
5137 {nullptr, 1}, 0x01, {nullptr, 0}, {nullptr, 0}};
5138
5139 foreach_pldm_package_component_image_information(pkg, info, rc)
5140 {
5141 EXPECT_EQ(info.component_classification,
5142 expected_info.component_classification);
5143 EXPECT_EQ(info.component_identifier,
5144 expected_info.component_identifier);
5145 EXPECT_EQ(info.component_comparison_stamp,
5146 expected_info.component_comparison_stamp);
5147 EXPECT_EQ(info.component_options.value,
5148 expected_info.component_options.value);
5149 EXPECT_EQ(info.requested_component_activation_method.value,
5150 expected_info.requested_component_activation_method.value);
5151 EXPECT_NE(nullptr, info.component_image.ptr);
5152 EXPECT_EQ(info.component_image.length,
5153 expected_info.component_image.length);
5154 EXPECT_EQ(info.component_version_string_type,
5155 expected_info.component_version_string_type);
5156 ASSERT_EQ(info.component_version_string.length, 4);
5157 EXPECT_EQ(memcmp("v0.2", info.component_version_string.ptr,
5158 info.component_version_string.length),
5159 0);
5160
5161 nr_infos++;
5162 }
5163 ASSERT_EQ(rc, 0);
5164
5165 EXPECT_EQ(nr_infos, 1);
5166}
5167#endif
5168
5169#ifdef LIBPLDM_API_TESTING
5170TEST(DecodePldmFirmwareUpdatePackage, invalidDownstreamDeviceIteration)
5171{
5172 const std::array<uint8_t, 102> package{
5173 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5174 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5175 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5176 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5177
5178 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5179 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c,
5180 0x01, 0x00, 0x00,
5181
5182 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5183 0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5184 0x01, 0x04, 'v', '0', '.', '2', 0x00, 0x00, 0x00, 0x00,
5185
5186 0xb5, 0x3f, 0xf6, 0x6a,
5187
5188 0x5a,
5189 };
5190
5191 struct pldm_package_downstream_device_id_record ddrec;
5192 struct pldm_package_firmware_device_id_record fdrec;
5193 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR01H(pin);
5194 pldm_package_header_information_pad hdr;
5195 struct pldm_package pkg{};
5196 int nr_fdrec_desc = 0;
5197 int nr_fdrec = 0;
5198 int rc;
5199
5200 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00005201 &pin, &hdr, &pkg, 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005202 ASSERT_EQ(rc, 0);
5203
5204 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5205 hdr.package_header_identifier,
5206 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5207 0);
5208 EXPECT_EQ(hdr.package_header_format_revision, 1);
5209
5210 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5211 0x16, 0x03, 0x00, 0x00, 0x00,
5212 0x00, 0x76, 0x02};
5213 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5214 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5215 timestamp.size()),
5216 0);
5217
5218 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5219 EXPECT_EQ(hdr.package_version_string_type, 1);
5220 ASSERT_EQ(hdr.package_version_string.length, 4);
5221 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5222 hdr.package_version_string.length),
5223 0);
5224 EXPECT_NE(pkg.areas.ptr, nullptr);
5225 EXPECT_NE(pkg.areas.length, 0);
5226 EXPECT_NE(pkg.package.ptr, nullptr);
5227 EXPECT_NE(pkg.package.length, 0);
5228
5229 foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
5230 {
5231 struct pldm_descriptor desc;
5232
5233 EXPECT_EQ(fdrec.descriptor_count, 1);
5234 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5235 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5236 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5237 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5238 fdrec.component_image_set_version_string.length),
5239 0);
5240 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5241 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5242 EXPECT_NE(fdrec.record_descriptors.length, 0);
5243 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5244 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5245
5246 foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
5247 desc, rc)
5248 {
5249 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5250
5251 EXPECT_EQ(desc.descriptor_type, 1);
5252 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5253 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5254 sizeof(iana_pen_dmtf)),
5255 0);
5256
5257 nr_fdrec_desc++;
5258 }
5259 ASSERT_EQ(rc, 0);
5260
5261 nr_fdrec++;
5262 }
5263 ASSERT_EQ(rc, 0);
5264
5265 EXPECT_EQ(nr_fdrec, 1);
5266 EXPECT_EQ(nr_fdrec_desc, 1);
5267
5268 foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
5269 EXPECT_NE(rc, 0);
5270}
5271#endif
5272
5273#ifdef LIBPLDM_API_TESTING
5274TEST(DecodePldmFirmwareUpdatePackage, p2v1h1fd1fdd1cii)
Andrew Jeffery2613c272025-03-12 14:15:41 +10305275{
5276 const std::array<uint8_t, 102> package{
5277 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
5278 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x65, 0x00, 0x00, 0xe9, 0x07,
5279 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08,
5280 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5281
5282 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
5283 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c,
5284 0x01, 0x00, 0x00,
5285
5286 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
5287 0x00, 0x01, 0x00, 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5288 0x01, 0x04, 'v', '0', '.', '2', 0x00, 0x00, 0x00, 0x00,
5289
5290 0xb5, 0x3f, 0xf6, 0x6a,
5291
5292 0x5a,
5293 };
5294
5295 struct pldm_package_downstream_device_id_record ddrec;
5296 struct pldm_package_component_image_information info;
5297 struct pldm_package_firmware_device_id_record fdrec;
5298 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5299 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005300 struct pldm_package pkg{};
Andrew Jeffery2613c272025-03-12 14:15:41 +10305301 int nr_fdrec_desc = 0;
5302 int nr_ddrec_desc = 0;
5303 int nr_fdrec = 0;
5304 int nr_ddrec = 0;
5305 int nr_infos = 0;
5306 int rc;
5307
5308 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00005309 &pin, &hdr, &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10305310 ASSERT_EQ(rc, 0);
5311
5312 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.data(),
5313 hdr.package_header_identifier,
5314 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.size()),
5315 0);
5316 EXPECT_EQ(hdr.package_header_format_revision, 1);
5317
5318 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5319 0x16, 0x03, 0x00, 0x00, 0x00,
5320 0x00, 0x76, 0x02};
5321 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5322 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5323 timestamp.size()),
5324 0);
5325
5326 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5327 EXPECT_EQ(hdr.package_version_string_type, 1);
5328 ASSERT_EQ(hdr.package_version_string.length, 4);
5329 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5330 hdr.package_version_string.length),
5331 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005332 EXPECT_NE(pkg.areas.ptr, nullptr);
5333 EXPECT_NE(pkg.areas.length, 0);
5334 EXPECT_NE(pkg.package.ptr, nullptr);
5335 EXPECT_NE(pkg.package.length, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10305336
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005337 foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
Andrew Jeffery2613c272025-03-12 14:15:41 +10305338 {
5339 struct pldm_descriptor desc;
5340
5341 EXPECT_EQ(fdrec.descriptor_count, 1);
5342 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5343 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5344 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5345 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5346 fdrec.component_image_set_version_string.length),
5347 0);
5348 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5349 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5350 EXPECT_NE(fdrec.record_descriptors.length, 0);
5351 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5352 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5353
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005354 foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
Andrew Jeffery2613c272025-03-12 14:15:41 +10305355 desc, rc)
5356 {
5357 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5358
5359 EXPECT_EQ(desc.descriptor_type, 1);
5360 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5361 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5362 sizeof(iana_pen_dmtf)),
5363 0);
5364
5365 nr_fdrec_desc++;
5366 }
5367 ASSERT_EQ(rc, 0);
5368
5369 nr_fdrec++;
5370 }
5371 ASSERT_EQ(rc, 0);
5372
5373 EXPECT_EQ(nr_fdrec, 1);
5374 EXPECT_EQ(nr_fdrec_desc, 1);
5375
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005376 foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
Andrew Jeffery2613c272025-03-12 14:15:41 +10305377 {
5378 struct pldm_descriptor desc;
5379
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005380 foreach_pldm_package_downstream_device_id_record_descriptor(pkg, ddrec,
Andrew Jeffery2613c272025-03-12 14:15:41 +10305381 desc, rc)
5382 {
Andrew Jeffery2613c272025-03-12 14:15:41 +10305383 nr_ddrec_desc++;
5384 }
5385 ASSERT_EQ(rc, 0);
5386
5387 nr_ddrec++;
5388 }
5389 ASSERT_EQ(rc, 0);
5390
5391 EXPECT_EQ(nr_ddrec, 0);
5392 EXPECT_EQ(nr_ddrec_desc, 0);
5393
5394 static const pldm_package_component_image_information expected_info{
Carter Chenf72cf6f2025-06-24 15:34:49 +08005395 0x000a, 0x0000, 0xffffffff, {0}, {1},
5396 {nullptr, 1}, 0x01, {nullptr, 0}, {nullptr, 0}};
Andrew Jeffery2613c272025-03-12 14:15:41 +10305397
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005398 foreach_pldm_package_component_image_information(pkg, info, rc)
Andrew Jeffery2613c272025-03-12 14:15:41 +10305399 {
5400 EXPECT_EQ(info.component_classification,
5401 expected_info.component_classification);
5402 EXPECT_EQ(info.component_identifier,
5403 expected_info.component_identifier);
5404 EXPECT_EQ(info.component_comparison_stamp,
5405 expected_info.component_comparison_stamp);
5406 EXPECT_EQ(info.component_options.value,
5407 expected_info.component_options.value);
5408 EXPECT_EQ(info.requested_component_activation_method.value,
5409 expected_info.requested_component_activation_method.value);
5410 EXPECT_NE(nullptr, info.component_image.ptr);
5411 EXPECT_EQ(info.component_image.length,
5412 expected_info.component_image.length);
5413 EXPECT_EQ(info.component_version_string_type,
5414 expected_info.component_version_string_type);
5415 ASSERT_EQ(info.component_version_string.length, 4);
5416 EXPECT_EQ(memcmp("v0.2", info.component_version_string.ptr,
5417 info.component_version_string.length),
5418 0);
5419
5420 nr_infos++;
5421 }
5422 ASSERT_EQ(rc, 0);
5423
5424 EXPECT_EQ(nr_infos, 1);
5425}
5426#endif
5427
5428#ifdef LIBPLDM_API_TESTING
5429TEST(DecodePldmFirmwareUpdatePackage, v2h1fd1fdd1dd1ddd2cii)
5430{
5431 const std::array<uint8_t, 150> package{
5432 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
5433 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5a, 0x02, 0x94, 0x00, 0x00,
5434 0xe9, 0x07, 0x03, 0x0b, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00,
5435 0x76, 0x02, 0x08, 0x00, 0x01, 0x04, 't', 'e', 's', 't',
5436
5437 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5438 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
5439 0x00, 0x9c, 0x01, 0x00, 0x00,
5440
5441 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04,
5442 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
5443 0x00, 0x9c, 0x01, 0x00, 0x00,
5444
5445 0x02, 0x00,
5446
5447 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5448 0x01, 0x00, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5449 0x01, 0x04, 'v', '0', '.', '2',
5450
5451 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
5452 0x01, 0x00, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
5453 0x01, 0x04, 'v', '2', '.', '0',
5454
5455 0xd3, 0x5c, 0x1c, 0x8a,
5456
5457 0x5a,
5458
5459 0xa5,
5460 };
5461 struct pldm_package_downstream_device_id_record ddrec;
5462 struct pldm_package_component_image_information info;
5463 struct pldm_package_firmware_device_id_record fdrec;
5464 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR02H(pin);
5465 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005466 struct pldm_package pkg{};
Andrew Jeffery2613c272025-03-12 14:15:41 +10305467 int nr_fdrec_desc = 0;
5468 int nr_ddrec_desc = 0;
5469 int nr_fdrec = 0;
5470 int nr_ddrec = 0;
5471 int nr_infos = 0;
5472 int rc;
5473
5474 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00005475 &pin, &hdr, &pkg, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10305476 ASSERT_EQ(rc, 0);
5477
5478 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.data(),
5479 hdr.package_header_identifier,
5480 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_1.size()),
5481 0);
5482 EXPECT_EQ(hdr.package_header_format_revision, 2);
5483
5484 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5485 0x16, 0x03, 0x00, 0x00, 0x00,
5486 0x00, 0x76, 0x02};
5487 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5488 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5489 timestamp.size()),
5490 0);
5491
5492 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5493 EXPECT_EQ(hdr.package_version_string_type, 1);
5494 ASSERT_EQ(hdr.package_version_string.length, 4);
5495 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5496 hdr.package_version_string.length),
5497 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005498 EXPECT_NE(pkg.areas.ptr, nullptr);
5499 EXPECT_NE(pkg.areas.length, 0);
5500 EXPECT_NE(pkg.package.ptr, nullptr);
5501 EXPECT_NE(pkg.package.length, 0);
Andrew Jeffery2613c272025-03-12 14:15:41 +10305502
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005503 foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
Andrew Jeffery2613c272025-03-12 14:15:41 +10305504 {
5505 struct pldm_descriptor desc;
5506
5507 EXPECT_EQ(fdrec.descriptor_count, 1);
5508 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5509 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5510 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5511 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5512 fdrec.component_image_set_version_string.length),
5513 0);
5514 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5515 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5516 EXPECT_NE(fdrec.record_descriptors.length, 0);
5517 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5518 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5519
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005520 foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
Andrew Jeffery2613c272025-03-12 14:15:41 +10305521 desc, rc)
5522 {
5523 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5524
5525 EXPECT_EQ(desc.descriptor_type, 1);
5526 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5527 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5528 sizeof(iana_pen_dmtf)),
5529 0);
5530
5531 nr_fdrec_desc++;
5532 }
5533 ASSERT_EQ(rc, 0);
5534
5535 nr_fdrec++;
5536 }
5537 ASSERT_EQ(rc, 0);
5538
5539 EXPECT_EQ(nr_fdrec, 1);
5540 EXPECT_EQ(nr_fdrec_desc, 1);
5541
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005542 foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
Andrew Jeffery2613c272025-03-12 14:15:41 +10305543 {
5544 struct pldm_descriptor desc;
5545
5546 EXPECT_EQ(ddrec.descriptor_count, 1);
5547 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5548 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5549 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5550 EXPECT_EQ(
5551 memcmp("v1.0",
5552 ddrec.self_contained_activation_min_version_string.ptr,
5553 ddrec.self_contained_activation_min_version_string.length),
5554 0);
5555 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5556 0);
5557 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5558 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5559 EXPECT_NE(ddrec.record_descriptors.length, 0);
5560 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5561 EXPECT_EQ(ddrec.package_data.length, 0);
5562
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005563 foreach_pldm_package_downstream_device_id_record_descriptor(pkg, ddrec,
Andrew Jeffery2613c272025-03-12 14:15:41 +10305564 desc, rc)
5565 {
5566 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5567
5568 EXPECT_EQ(desc.descriptor_type, 1);
5569 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5570 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5571 sizeof(iana_pen_dmtf)),
5572 0);
5573
5574 nr_ddrec_desc++;
5575 }
5576 ASSERT_EQ(rc, 0);
5577
5578 nr_ddrec++;
5579 }
5580 ASSERT_EQ(rc, 0);
5581
5582 EXPECT_EQ(nr_ddrec, 1);
5583 EXPECT_EQ(nr_ddrec_desc, 1);
5584
5585 static const std::array<const char*, 2> component_versions = {
5586 "v0.2",
5587 "v2.0",
5588 };
5589 static const std::array<pldm_package_component_image_information, 2>
5590 expected_infos{{{0x000a,
5591 0x0000,
5592 0xffffffff,
5593 {0},
5594 {1},
5595 {nullptr, 1},
5596 0x01,
Carter Chenf72cf6f2025-06-24 15:34:49 +08005597 {nullptr, 0},
Andrew Jeffery2613c272025-03-12 14:15:41 +10305598 {nullptr, 0}},
5599 {0x000a,
5600 0x0000,
5601 0xffffffff,
5602 {0},
5603 {1},
5604 {nullptr, 1},
5605 0x01,
Carter Chenf72cf6f2025-06-24 15:34:49 +08005606 {nullptr, 0},
Andrew Jeffery2613c272025-03-12 14:15:41 +10305607 {nullptr, 0}}}};
5608 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5609
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005610 foreach_pldm_package_component_image_information(pkg, info, rc)
Andrew Jeffery2613c272025-03-12 14:15:41 +10305611 {
5612 const struct pldm_package_component_image_information* expected;
5613 const char* version;
5614 uint8_t image;
5615
5616 expected = &expected_infos.at(nr_infos);
5617 version = component_versions.at(nr_infos);
5618 image = expected_images.at(nr_infos);
5619
5620 EXPECT_EQ(info.component_classification,
5621 expected->component_classification);
5622 EXPECT_EQ(info.component_identifier, expected->component_identifier);
5623 EXPECT_EQ(info.component_comparison_stamp,
5624 expected->component_comparison_stamp);
5625 EXPECT_EQ(info.component_options.value,
5626 expected->component_options.value);
5627 EXPECT_EQ(info.requested_component_activation_method.value,
5628 expected->requested_component_activation_method.value);
5629 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5630 EXPECT_EQ(info.component_image.length,
5631 expected->component_image.length);
5632 EXPECT_EQ(*info.component_image.ptr, image);
5633 EXPECT_EQ(info.component_version_string_type,
5634 expected->component_version_string_type);
5635 ASSERT_EQ(info.component_version_string.length, 4);
5636 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5637 info.component_version_string.length),
5638 0);
5639
5640 nr_infos++;
5641 }
5642 ASSERT_EQ(rc, 0);
5643
5644 EXPECT_EQ(nr_infos, 2);
5645}
5646#endif
Carter Chenf72cf6f2025-06-24 15:34:49 +08005647
5648#ifdef LIBPLDM_API_TESTING
5649TEST(DecodePldmFirmwareUpdatePackage, v3h1fd1fdd1dd1ddd2cii)
5650{
5651 const std::array<uint8_t, 166> package{
5652 0x31, 0x19, 0xce, 0x2f, 0xe8, 0x0a, 0x4a, 0x99, 0xaf, 0x6d, 0x46, 0xf8,
5653 0xb1, 0x21, 0xf6, 0xbf, 0x03, 0xA4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5654 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5655 't', 'e', 's', 't',
5656
5657 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5658 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5659 0x00,
5660
5661 0x01, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5662 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04, 0x00, 0x9c, 0x01, 0x00,
5663 0x00,
5664
5665 0x02, 0x00,
5666
5667 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5668 0xA4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '0',
5669 '.', '2', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5670
5671 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5672 0xA5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '2',
5673 '.', '0', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5674
5675 0xed, 0x9d, 0x97, 0x7a,
5676
5677 0x5a,
5678
5679 0xa5,
5680
5681 };
5682
5683 struct pldm_package_downstream_device_id_record ddrec;
5684 struct pldm_package_component_image_information info;
5685 struct pldm_package_firmware_device_id_record fdrec;
5686 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR03H(pin);
5687 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005688 struct pldm_package pkg{};
Carter Chenf72cf6f2025-06-24 15:34:49 +08005689 int nr_fdrec_desc = 0;
5690 int nr_ddrec_desc = 0;
5691 int nr_fdrec = 0;
5692 int nr_ddrec = 0;
5693 int nr_infos = 0;
5694 int rc;
5695
5696 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00005697 &pin, &hdr, &pkg, 0);
Carter Chenf72cf6f2025-06-24 15:34:49 +08005698 ASSERT_EQ(rc, 0);
5699
5700 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.data(),
5701 hdr.package_header_identifier,
5702 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_2.size()),
5703 0);
5704 EXPECT_EQ(hdr.package_header_format_revision, 3);
5705
5706 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5707 0x16, 0x03, 0x00, 0x00, 0x00,
5708 0x00, 0x76, 0x02};
5709 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5710 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5711 timestamp.size()),
5712 0);
5713
5714 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5715 EXPECT_EQ(hdr.package_version_string_type, 1);
5716 ASSERT_EQ(hdr.package_version_string.length, 4);
5717 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5718 hdr.package_version_string.length),
5719 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005720 EXPECT_NE(pkg.areas.ptr, nullptr);
5721 EXPECT_NE(pkg.areas.length, 0);
5722 EXPECT_NE(pkg.package.ptr, nullptr);
5723 EXPECT_NE(pkg.package.length, 0);
Carter Chenf72cf6f2025-06-24 15:34:49 +08005724
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005725 foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
Carter Chenf72cf6f2025-06-24 15:34:49 +08005726 {
5727 struct pldm_descriptor desc;
5728
5729 EXPECT_EQ(fdrec.descriptor_count, 1);
5730 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5731 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5732 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5733 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5734 fdrec.component_image_set_version_string.length),
5735 0);
5736 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5737 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5738 EXPECT_NE(fdrec.record_descriptors.length, 0);
5739 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5740 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5741
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005742 foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
Carter Chenf72cf6f2025-06-24 15:34:49 +08005743 desc, rc)
5744 {
5745 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5746
5747 EXPECT_EQ(desc.descriptor_type, 1);
5748 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5749 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5750 sizeof(iana_pen_dmtf)),
5751 0);
5752
5753 nr_fdrec_desc++;
5754 }
5755 ASSERT_EQ(rc, 0);
5756
5757 nr_fdrec++;
5758 }
5759 ASSERT_EQ(rc, 0);
5760
5761 EXPECT_EQ(nr_fdrec, 1);
5762 EXPECT_EQ(nr_fdrec_desc, 1);
5763
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005764 foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
Carter Chenf72cf6f2025-06-24 15:34:49 +08005765 {
5766 struct pldm_descriptor desc;
5767
5768 EXPECT_EQ(ddrec.descriptor_count, 1);
5769 EXPECT_EQ(ddrec.update_option_flags.value, 0);
5770 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
5771 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
5772 EXPECT_EQ(
5773 memcmp("v1.0",
5774 ddrec.self_contained_activation_min_version_string.ptr,
5775 ddrec.self_contained_activation_min_version_string.length),
5776 0);
5777 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
5778 0);
5779 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
5780 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
5781 EXPECT_NE(ddrec.record_descriptors.length, 0);
5782 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
5783 EXPECT_EQ(ddrec.package_data.length, 0);
5784
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005785 foreach_pldm_package_downstream_device_id_record_descriptor(pkg, ddrec,
Carter Chenf72cf6f2025-06-24 15:34:49 +08005786 desc, rc)
5787 {
5788 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5789
5790 EXPECT_EQ(desc.descriptor_type, 1);
5791 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5792 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5793 sizeof(iana_pen_dmtf)),
5794 0);
5795
5796 nr_ddrec_desc++;
5797 }
5798 ASSERT_EQ(rc, 0);
5799
5800 nr_ddrec++;
5801 }
5802 ASSERT_EQ(rc, 0);
5803
5804 EXPECT_EQ(nr_ddrec, 1);
5805 EXPECT_EQ(nr_ddrec_desc, 1);
5806
5807 static const std::array<const char*, 2> component_versions = {
5808 "v0.2",
5809 "v2.0",
5810 };
5811
5812 static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
5813 0x78};
5814
5815 static const std::array<pldm_package_component_image_information, 2>
5816 expected_infos{
5817 {{0x000a,
5818 0x0000,
5819 0xffffffff,
5820 {0},
5821 {1},
5822 {nullptr, 1},
5823 0x01,
5824 {nullptr, 0},
5825 {expected_opaque_data.data(), expected_opaque_data.size()}},
5826 {0x000a,
5827 0x0000,
5828 0xffffffff,
5829 {0},
5830 {1},
5831 {nullptr, 1},
5832 0x01,
5833 {nullptr, 0},
5834 {expected_opaque_data.data(), expected_opaque_data.size()}}}};
5835 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
5836
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005837 foreach_pldm_package_component_image_information(pkg, info, rc)
Carter Chenf72cf6f2025-06-24 15:34:49 +08005838 {
5839 const struct pldm_package_component_image_information* expected;
5840 const char* version;
5841 uint8_t image;
5842
5843 expected = &expected_infos.at(nr_infos);
5844 version = component_versions.at(nr_infos);
5845 image = expected_images.at(nr_infos);
5846
5847 EXPECT_EQ(info.component_classification,
5848 expected->component_classification);
5849 EXPECT_EQ(info.component_identifier, expected->component_identifier);
5850 EXPECT_EQ(info.component_comparison_stamp,
5851 expected->component_comparison_stamp);
5852 EXPECT_EQ(info.component_options.value,
5853 expected->component_options.value);
5854 EXPECT_EQ(info.requested_component_activation_method.value,
5855 expected->requested_component_activation_method.value);
5856 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
5857 EXPECT_EQ(info.component_image.length,
5858 expected->component_image.length);
5859 EXPECT_EQ(*info.component_image.ptr, image);
5860 EXPECT_EQ(info.component_version_string_type,
5861 expected->component_version_string_type);
5862 ASSERT_EQ(info.component_version_string.length, 4);
5863 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
5864 info.component_version_string.length),
5865 0);
5866 EXPECT_EQ(info.component_opaque_data.length,
5867 expected->component_opaque_data.length);
5868 EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
5869 expected->component_opaque_data.ptr,
5870 expected->component_opaque_data.length),
5871 0);
5872 nr_infos++;
5873 }
5874 ASSERT_EQ(rc, 0);
5875
5876 EXPECT_EQ(nr_infos, 2);
5877}
Carter Chen01782742025-06-25 13:53:50 +08005878#endif
5879
5880#ifdef LIBPLDM_API_TESTING
5881TEST(DecodePldmFirmwareUpdatePackage, v4h1fd1fdd1dd1ddd2cii)
5882{
5883 const std::array<uint8_t, 182> package{
5884 0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
5885 0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
5886 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
5887 't', 'e', 's', 't',
5888
5889 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5890 0x02, 0x00, 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
5891 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
5892
5893 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
5894 0x02, 0x00, 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
5895 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
5896
5897 0x02, 0x00,
5898
5899 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5900 0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '0',
5901 '.', '2', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5902
5903 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
5904 0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '2',
5905 '.', '0', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
5906
5907 0xf7, 0xf7, 0xfd, 0x79,
5908
5909 0x46, 0xf0, 0x31, 0xa7,
5910
5911 0x5a,
5912
5913 0xa5,
5914
5915 };
5916
5917 struct pldm_package_downstream_device_id_record ddrec;
5918 struct pldm_package_component_image_information info;
5919 struct pldm_package_firmware_device_id_record fdrec;
5920 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
5921 pldm_package_header_information_pad hdr;
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005922 struct pldm_package pkg{};
Carter Chen01782742025-06-25 13:53:50 +08005923 int nr_fdrec_desc = 0;
5924 int nr_ddrec_desc = 0;
5925 int nr_fdrec = 0;
5926 int nr_ddrec = 0;
5927 int nr_infos = 0;
5928 int rc;
5929
5930 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00005931 &pin, &hdr, &pkg, 0);
Carter Chen01782742025-06-25 13:53:50 +08005932 ASSERT_EQ(rc, 0);
5933
5934 EXPECT_EQ(memcmp(PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3.data(),
5935 hdr.package_header_identifier,
5936 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_3.size()),
5937 0);
5938 EXPECT_EQ(hdr.package_header_format_revision, 4);
5939
5940 static const std::array<uint8_t, 13> timestamp{0x00, 0xe9, 0x07, 0x03, 0x0b,
5941 0x16, 0x03, 0x00, 0x00, 0x00,
5942 0x00, 0x76, 0x02};
5943 ASSERT_EQ(timestamp.size(), sizeof(hdr.package_release_date_time));
5944 EXPECT_EQ(memcmp(timestamp.data(), hdr.package_release_date_time,
5945 timestamp.size()),
5946 0);
5947
5948 EXPECT_EQ(hdr.component_bitmap_bit_length, 8);
5949 EXPECT_EQ(hdr.package_version_string_type, 1);
5950 ASSERT_EQ(hdr.package_version_string.length, 4);
5951 EXPECT_EQ(memcmp("test", hdr.package_version_string.ptr,
5952 hdr.package_version_string.length),
5953 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005954 EXPECT_NE(pkg.areas.ptr, nullptr);
5955 EXPECT_NE(pkg.areas.length, 0);
5956 EXPECT_NE(pkg.package.ptr, nullptr);
5957 EXPECT_NE(pkg.package.length, 0);
Carter Chen01782742025-06-25 13:53:50 +08005958
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005959 foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
Carter Chen01782742025-06-25 13:53:50 +08005960 {
5961 struct pldm_descriptor desc;
5962
5963 static const uint8_t expected_reference_manifest_data[] = {0x87, 0x65};
5964
5965 EXPECT_EQ(fdrec.descriptor_count, 1);
5966 EXPECT_EQ(fdrec.device_update_option_flags.value, 0);
5967 EXPECT_EQ(fdrec.component_image_set_version_string_type, 1);
5968 ASSERT_EQ(fdrec.component_image_set_version_string.length, 4);
5969 EXPECT_EQ(memcmp("v0.1", fdrec.component_image_set_version_string.ptr,
5970 fdrec.component_image_set_version_string.length),
5971 0);
5972 ASSERT_EQ(fdrec.applicable_components.bitmap.length, 1);
5973 EXPECT_EQ(*fdrec.applicable_components.bitmap.ptr, 1);
5974 EXPECT_NE(fdrec.record_descriptors.length, 0);
5975 EXPECT_NE(fdrec.record_descriptors.ptr, nullptr);
5976 ASSERT_EQ(fdrec.firmware_device_package_data.length, 0);
5977 EXPECT_EQ(fdrec.reference_manifest_data.length,
5978 sizeof(expected_reference_manifest_data));
5979 EXPECT_EQ(memcmp(fdrec.reference_manifest_data.ptr,
5980 expected_reference_manifest_data,
5981 sizeof(expected_reference_manifest_data)),
5982 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00005983 foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
Carter Chen01782742025-06-25 13:53:50 +08005984 desc, rc)
5985 {
5986 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
5987
5988 EXPECT_EQ(desc.descriptor_type, 1);
5989 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
5990 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
5991 sizeof(iana_pen_dmtf)),
5992 0);
5993
5994 nr_fdrec_desc++;
5995 }
5996 ASSERT_EQ(rc, 0);
5997
5998 nr_fdrec++;
5999 }
6000 ASSERT_EQ(rc, 0);
6001
6002 EXPECT_EQ(nr_fdrec, 1);
6003 EXPECT_EQ(nr_fdrec_desc, 1);
6004
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00006005 foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
Carter Chen01782742025-06-25 13:53:50 +08006006 {
6007 struct pldm_descriptor desc;
6008
6009 static const uint8_t expected_reference_manifest_data[] = {0x87, 0x65};
6010
6011 EXPECT_EQ(ddrec.descriptor_count, 1);
6012 EXPECT_EQ(ddrec.update_option_flags.value, 0);
6013 EXPECT_EQ(ddrec.self_contained_activation_min_version_string_type, 1);
6014 ASSERT_EQ(ddrec.self_contained_activation_min_version_string.length, 4);
6015 EXPECT_EQ(
6016 memcmp("v1.0",
6017 ddrec.self_contained_activation_min_version_string.ptr,
6018 ddrec.self_contained_activation_min_version_string.length),
6019 0);
6020 EXPECT_EQ(ddrec.self_contained_activation_min_version_comparison_stamp,
6021 0);
6022 ASSERT_EQ(ddrec.applicable_components.bitmap.length, 1);
6023 EXPECT_EQ(*ddrec.applicable_components.bitmap.ptr, 2);
6024 EXPECT_NE(ddrec.record_descriptors.length, 0);
6025 EXPECT_NE(ddrec.record_descriptors.ptr, nullptr);
6026 EXPECT_EQ(ddrec.package_data.length, 0);
6027 EXPECT_EQ(fdrec.reference_manifest_data.length,
6028 sizeof(expected_reference_manifest_data));
6029 EXPECT_EQ(memcmp(fdrec.reference_manifest_data.ptr,
6030 expected_reference_manifest_data,
6031 sizeof(expected_reference_manifest_data)),
6032 0);
6033
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00006034 foreach_pldm_package_downstream_device_id_record_descriptor(pkg, ddrec,
Carter Chen01782742025-06-25 13:53:50 +08006035 desc, rc)
6036 {
6037 static const uint8_t iana_pen_dmtf[] = {0x9c, 0x01, 0x00, 0x00};
6038
6039 EXPECT_EQ(desc.descriptor_type, 1);
6040 ASSERT_EQ(desc.descriptor_length, sizeof(iana_pen_dmtf));
6041 EXPECT_EQ(memcmp(iana_pen_dmtf, desc.descriptor_data,
6042 sizeof(iana_pen_dmtf)),
6043 0);
6044
6045 nr_ddrec_desc++;
6046 }
6047 ASSERT_EQ(rc, 0);
6048
6049 nr_ddrec++;
6050 }
6051 ASSERT_EQ(rc, 0);
6052
6053 EXPECT_EQ(nr_ddrec, 1);
6054 EXPECT_EQ(nr_ddrec_desc, 1);
6055
6056 static const std::array<const char*, 2> component_versions = {
6057 "v0.2",
6058 "v2.0",
6059 };
6060
6061 static std::array<uint8_t, 4> expected_opaque_data = {0x12, 0x34, 0x56,
6062 0x78};
6063
6064 static const std::array<pldm_package_component_image_information, 2>
6065 expected_infos{
6066 {{0x000a,
6067 0x0000,
6068 0xffffffff,
6069 {0},
6070 {1},
6071 {nullptr, 1},
6072 0x01,
6073 {nullptr, 0},
6074 {expected_opaque_data.data(), expected_opaque_data.size()}},
6075 {0x000a,
6076 0x0000,
6077 0xffffffff,
6078 {0},
6079 {1},
6080 {nullptr, 1},
6081 0x01,
6082 {nullptr, 0},
6083 {expected_opaque_data.data(), expected_opaque_data.size()}}}};
6084 static const std::array<uint8_t, 2> expected_images{0x5a, 0xa5};
6085
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00006086 foreach_pldm_package_component_image_information(pkg, info, rc)
Carter Chen01782742025-06-25 13:53:50 +08006087 {
6088 const struct pldm_package_component_image_information* expected;
6089 const char* version;
6090 uint8_t image;
6091
6092 expected = &expected_infos.at(nr_infos);
6093 version = component_versions.at(nr_infos);
6094 image = expected_images.at(nr_infos);
6095
6096 EXPECT_EQ(info.component_classification,
6097 expected->component_classification);
6098 EXPECT_EQ(info.component_identifier, expected->component_identifier);
6099 EXPECT_EQ(info.component_comparison_stamp,
6100 expected->component_comparison_stamp);
6101 EXPECT_EQ(info.component_options.value,
6102 expected->component_options.value);
6103 EXPECT_EQ(info.requested_component_activation_method.value,
6104 expected->requested_component_activation_method.value);
6105 EXPECT_NE(info.component_image.ptr, expected->component_image.ptr);
6106 EXPECT_EQ(info.component_image.length,
6107 expected->component_image.length);
6108 EXPECT_EQ(*info.component_image.ptr, image);
6109 EXPECT_EQ(info.component_version_string_type,
6110 expected->component_version_string_type);
6111 ASSERT_EQ(info.component_version_string.length, 4);
6112 EXPECT_EQ(memcmp(version, info.component_version_string.ptr,
6113 info.component_version_string.length),
6114 0);
6115 EXPECT_EQ(info.component_opaque_data.length,
6116 expected->component_opaque_data.length);
6117 EXPECT_EQ(memcmp(info.component_opaque_data.ptr,
6118 expected->component_opaque_data.ptr,
6119 expected->component_opaque_data.length),
6120 0);
6121
6122 nr_infos++;
6123 }
6124 ASSERT_EQ(rc, 0);
6125
6126 EXPECT_EQ(nr_infos, 2);
6127}
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00006128#endif
6129
6130#ifdef LIBPLDM_API_TESTING
6131TEST(DecodePldmFirmwareUpdatePackage, downstreamDeviceBeforeFirmwareDevice)
6132{
6133 const std::array<uint8_t, 182> package{
6134 0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
6135 0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
6136 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
6137 't', 'e', 's', 't',
6138
6139 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6140 0x02, 0x00, 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
6141 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6142
6143 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6144 0x02, 0x00, 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
6145 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6146
6147 0x02, 0x00,
6148
6149 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6150 0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '0',
6151 '.', '2', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6152
6153 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6154 0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '2',
6155 '.', '0', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6156
6157 0xf7, 0xf7, 0xfd, 0x79,
6158
6159 0x46, 0xf0, 0x31, 0xa7,
6160
6161 0x5a,
6162
6163 0xa5,
6164
6165 };
6166
6167 struct pldm_package_downstream_device_id_record ddrec;
6168 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
6169 pldm_package_header_information_pad hdr;
6170 struct pldm_package pkg{};
6171 int rc;
6172
6173 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00006174 &pin, &hdr, &pkg, 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00006175 ASSERT_EQ(rc, 0);
6176
6177 foreach_pldm_package_downstream_device_id_record(pkg, ddrec, rc)
6178 {
6179 }
6180 EXPECT_NE(rc, 0);
6181}
6182#endif
6183
6184#ifdef LIBPLDM_API_TESTING
6185TEST(DecodePldmFirmwareUpdatePackage, componentImageInfosBeforeFirmwareDevice)
6186{
6187 const std::array<uint8_t, 182> package{
6188 0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
6189 0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
6190 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
6191 't', 'e', 's', 't',
6192
6193 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6194 0x02, 0x00, 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
6195 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6196
6197 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6198 0x02, 0x00, 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
6199 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6200
6201 0x02, 0x00,
6202
6203 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6204 0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '0',
6205 '.', '2', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6206
6207 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6208 0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '2',
6209 '.', '0', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6210
6211 0xf7, 0xf7, 0xfd, 0x79,
6212
6213 0x46, 0xf0, 0x31, 0xa7,
6214
6215 0x5a,
6216
6217 0xa5,
6218
6219 };
6220
6221 struct pldm_package_component_image_information info;
6222 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
6223 pldm_package_header_information_pad hdr;
6224 struct pldm_package pkg{};
6225 int rc;
6226
6227 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00006228 &pin, &hdr, &pkg, 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00006229 ASSERT_EQ(rc, 0);
6230
6231 foreach_pldm_package_component_image_information(pkg, info, rc)
6232 {
6233 }
6234 EXPECT_NE(rc, 0);
6235}
6236#endif
6237
6238#ifdef LIBPLDM_API_TESTING
6239TEST(DecodePldmFirmwareUpdatePackage,
6240 p4v2ComponentImageInfosBeforeDownstreamDevice)
6241{
6242 const std::array<uint8_t, 182> package{
6243 0x7B, 0x29, 0x1C, 0x99, 0x6D, 0xB6, 0x42, 0x08, 0x80, 0x1B, 0x02, 0x02,
6244 0x6E, 0x46, 0x3C, 0x78, 0x04, 0xB4, 0x00, 0x00, 0xe9, 0x07, 0x03, 0x0b,
6245 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x76, 0x02, 0x08, 0x00, 0x01, 0x04,
6246 't', 'e', 's', 't',
6247
6248 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6249 0x02, 0x00, 0x00, 0x00, 0x01, 'v', '0', '.', '1', 0x01, 0x00, 0x04,
6250 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6251
6252 0x01, 0x1E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00,
6253 0x02, 0x00, 0x00, 0x00, 0x02, 'v', '1', '.', '0', 0x01, 0x00, 0x04,
6254 0x00, 0x9c, 0x01, 0x00, 0x00, 0x87, 0x65,
6255
6256 0x02, 0x00,
6257
6258 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6259 0xB4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '0',
6260 '.', '2', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6261
6262 0x0a, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00,
6263 0xB5, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x04, 'v', '2',
6264 '.', '0', 0x04, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x78,
6265
6266 0xf7, 0xf7, 0xfd, 0x79,
6267
6268 0x46, 0xf0, 0x31, 0xa7,
6269
6270 0x5a,
6271
6272 0xa5,
6273
6274 };
6275
6276 struct pldm_package_component_image_information info;
6277 struct pldm_package_firmware_device_id_record fdrec;
6278 DEFINE_PLDM_PACKAGE_FORMAT_PIN_FR04H(pin);
6279 pldm_package_header_information_pad hdr;
6280 struct pldm_package pkg{};
6281 int rc;
6282
6283 rc = decode_pldm_firmware_update_package(package.data(), package.size(),
Andrew Jeffery72442de2025-08-12 08:47:42 +00006284 &pin, &hdr, &pkg, 0);
Andrew Jefferyc53c6fe2025-08-11 07:44:38 +00006285 ASSERT_EQ(rc, 0);
6286
6287 foreach_pldm_package_firmware_device_id_record(pkg, fdrec, rc)
6288 {
6289 struct pldm_descriptor desc;
6290
6291 foreach_pldm_package_firmware_device_id_record_descriptor(pkg, fdrec,
6292 desc, rc)
6293 {
6294 }
6295 ASSERT_EQ(rc, 0);
6296 }
6297 ASSERT_EQ(rc, 0);
6298
6299 foreach_pldm_package_component_image_information(pkg, info, rc)
6300 {
6301 }
6302 EXPECT_NE(rc, 0);
6303}
6304#endif