blob: 05b7546160e7306b2ad1f490cb3d7fcd4e9324f6 [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 Jeffery150b06c2025-03-12 14:17:42 +103051static constexpr size_t PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 = 43;
52
53static constexpr std::array<uint8_t, PLDM_TIMESTAMP104_SIZE>
54 testPackageReleaseDateTime{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00};
Andrew Jefferye038b962025-03-06 16:04:59 +103056
Andrew Jeffery9c766792022-08-10 23:12:49 +093057TEST(DecodePackageHeaderInfo, goodPath)
58{
Andrew Jeffery9c766792022-08-10 23:12:49 +093059 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +093060 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +103061 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +103062 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +093063
Andrew Jefferya3eba612025-03-06 17:11:20 +103064 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +103065 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
66 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
68 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
69 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x61, 0xe3, 0x64, 0x6e};
Andrew Jeffery9c766792022-08-10 23:12:49 +093070 pldm_package_header_information pkgHeader{};
71 variable_field packageVersion{};
72
73 auto rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
74 packagerHeaderInfo.size(),
75 &pkgHeader, &packageVersion);
76
Andrew Jeffery150b06c2025-03-12 14:17:42 +103077 ASSERT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +093078 EXPECT_EQ(true,
79 std::equal(pkgHeader.uuid, pkgHeader.uuid + PLDM_FWUP_UUID_LENGTH,
Andrew Jefferye038b962025-03-06 16:04:59 +103080 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.begin(),
81 PLDM_FWUP_PACKAGE_HEADER_IDENTIFIER_V1_0.end()));
82 EXPECT_EQ(pkgHeader.package_header_format_version,
83 PLDM_FWUP_PACKAGE_HEADER_FORMAT_REVISION_V1_0);
Andrew Jeffery150b06c2025-03-12 14:17:42 +103084 EXPECT_EQ(pkgHeader.package_header_size, packageHeaderSize);
Andrew Jeffery9c766792022-08-10 23:12:49 +093085 EXPECT_EQ(true, std::equal(pkgHeader.package_release_date_time,
86 pkgHeader.package_release_date_time +
87 PLDM_TIMESTAMP104_SIZE,
Andrew Jeffery150b06c2025-03-12 14:17:42 +103088 testPackageReleaseDateTime.begin(),
89 testPackageReleaseDateTime.end()));
Andrew Jeffery9c766792022-08-10 23:12:49 +093090 EXPECT_EQ(pkgHeader.component_bitmap_bit_length, componentBitmapBitLength);
91 EXPECT_EQ(pkgHeader.package_version_string_type, PLDM_STR_TYPE_ASCII);
92 EXPECT_EQ(pkgHeader.package_version_string_length,
93 packageVersionStr.size());
94 std::string packageVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +093095 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +093096 reinterpret_cast<const char*>(packageVersion.ptr),
97 packageVersion.length);
98 EXPECT_EQ(packageVersionString, packageVersionStr);
99}
100
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030101TEST(DecodePackageHeaderInfo, invalidArguments)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930102{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930103 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
Andrew Jefferya3eba612025-03-06 17:11:20 +1030104 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030105 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930106
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030107 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030108 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
109 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
111 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
112 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030113
114 pldm_package_header_information packageHeader{};
115 variable_field packageVersion{};
116 int rc = 0;
117
118 rc = decode_pldm_package_header_info(nullptr, packagerHeaderInfo.size(),
119 &packageHeader, &packageVersion);
120 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
121
122 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
123 packagerHeaderInfo.size(), nullptr,
124 &packageVersion);
125 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
126
127 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
128 packagerHeaderInfo.size(),
129 &packageHeader, nullptr);
130 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
131}
132
133TEST(DecodePackageHeaderInfo, invalidPackageLengths)
134{
135 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
136 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030137 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030138
139 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030140 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
141 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
143 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
144 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030145
146 pldm_package_header_information packageHeader{};
147 variable_field packageVersion{};
148 int rc = 0;
149
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030150 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 0,
151 &packageHeader, &packageVersion);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030152 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030153
154 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 35,
155 &packageHeader, &packageVersion);
156 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
157
158 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(), 36,
159 &packageHeader, &packageVersion);
160 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
161
162 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
163 packagerHeaderInfo.size() - 1,
164 &packageHeader, &packageVersion);
165 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
166}
167
168TEST(DecodePackageHeaderInfo, unspecifiedPackageHeaderIdentifier)
169{
170 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
171 constexpr size_t packageHeaderSize =
172 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
173
174 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
175 0xff, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
176 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
178 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
179 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
180
181 pldm_package_header_information packageHeader{};
182 variable_field packageVersion{};
183 int rc = 0;
184
185 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
186 packagerHeaderInfo.size(),
187 &packageHeader, &packageVersion);
188 EXPECT_EQ(rc, PLDM_ERROR);
189}
190
191TEST(DecodePackageHeaderInfo, incongruentPackageHeaderFormatRevision)
192{
193 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
194 constexpr size_t packageHeaderSize =
195 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + 1 + packageVersionStr.size();
196
197 constexpr std::array<uint8_t, packageHeaderSize> packagerHeaderInfo{
198 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
199 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x02, 0x37, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
201 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
202 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
203
204 pldm_package_header_information packageHeader{};
205 variable_field packageVersion{};
206 int rc = 0;
207
208 rc = decode_pldm_package_header_info(packagerHeaderInfo.data(),
209 packagerHeaderInfo.size(),
210 &packageHeader, &packageVersion);
211 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030212}
213
214TEST(DecodePackageHeaderInfo, invalidPackageVersionStringType)
215{
216 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
217 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030218 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030219
220 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030221 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
222 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
223 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
224 0x00, 0x06, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
225 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery9c766792022-08-10 23:12:49 +0930226
227 pldm_package_header_information packageHeader{};
228 variable_field packageVersion{};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030229 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930230
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030231 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
232 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930233 &packageHeader, &packageVersion);
234 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030235}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930236
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030237TEST(DecodePackageHeaderInfo, invalidPackageVersionStringLength)
238{
239 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
240 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030241 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery9c766792022-08-10 23:12:49 +0930242
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030243 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030244 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
245 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
247 0x00, 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
248 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030249
250 pldm_package_header_information packageHeader{};
251 variable_field packageVersion{};
252 int rc = 0;
253
254 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
255 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930256 &packageHeader, &packageVersion);
257 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030258}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930259
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030260TEST(DecodePackageHeaderInfo, corruptPackageVersionStringLength)
261{
262 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
263 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030264 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030265
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030266 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
267 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
268 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x08,
270 0x00, 0x01, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
271 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030272
273 pldm_package_header_information packageHeader{};
274 variable_field packageVersion{};
275 int rc = 0;
276
277 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
278 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930279 &packageHeader, &packageVersion);
280 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030281}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930282
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030283TEST(DecodePackageHeaderInfo, invalidComponentBitmapBitLength)
284{
285 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
286 constexpr size_t packageHeaderSize =
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030287 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030288
289 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
Andrew Jeffery150b06c2025-03-12 14:17:42 +1030290 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
291 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x07,
293 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
294 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
295
296 pldm_package_header_information packageHeader{};
297 variable_field packageVersion{};
298 int rc = 0;
299
300 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
301 invalidPackagerHeaderInfo.size(),
302 &packageHeader, &packageVersion);
303 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
304}
305
306TEST(DecodePackageHeaderInfo, badChecksum)
307{
308 constexpr std::string_view packageVersionStr{"OpenBMCv1.0"};
309 constexpr size_t packageHeaderSize =
310 PLDM_FWUP_PACKAGE_HEADER_EMPTY_SIZE_V1_0 + packageVersionStr.size();
311
312 constexpr std::array<uint8_t, packageHeaderSize> invalidPackagerHeaderInfo{
313 0xf0, 0x18, 0x87, 0x8c, 0xcb, 0x7d, 0x49, 0x43, 0x98, 0x00, 0xa0,
314 0x2f, 0x05, 0x9a, 0xca, 0x02, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0c, 0xe5, 0x07, 0x00, 0x10,
316 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x76,
317 0x31, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x96, 0x8b, 0x5b, 0xcc};
Andrew Jeffery075a7dc2025-03-06 17:22:22 +1030318
319 pldm_package_header_information packageHeader{};
320 variable_field packageVersion{};
321 int rc = 0;
322
323 rc = decode_pldm_package_header_info(invalidPackagerHeaderInfo.data(),
324 invalidPackagerHeaderInfo.size(),
Andrew Jeffery9c766792022-08-10 23:12:49 +0930325 &packageHeader, &packageVersion);
326 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
327}
328
329TEST(DecodeFirmwareDeviceIdRecord, goodPath)
330{
331 constexpr uint8_t descriptorCount = 1;
332 // Continue component updates after failure
333 constexpr std::bitset<32> deviceUpdateFlag{1};
334 constexpr uint16_t componentBitmapBitLength = 16;
335 // Applicable Components - 1,2,5,8,9
336 std::vector<std::bitset<8>> applicableComponentsBitfield{0x93, 0x01};
337 // ComponentImageSetVersionString
338 constexpr std::string_view imageSetVersionStr{"VersionString1"};
339 // Initial descriptor - UUID
340 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
341 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
342 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
343 constexpr uint16_t fwDevicePkgDataLen = 2;
344 // FirmwareDevicePackageData
345 constexpr std::array<uint8_t, fwDevicePkgDataLen> fwDevicePkgData{0xab,
346 0xcd};
347 // Size of the firmware device ID record
348 constexpr uint16_t recordLen =
349 sizeof(pldm_firmware_device_id_record) +
350 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
351 imageSetVersionStr.size() + sizeof(pldm_descriptor_tlv) - 1 +
352 uuid.size() + fwDevicePkgData.size();
353 // Firmware device ID record
354 constexpr std::array<uint8_t, recordLen> record{
355 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x02,
356 0x00, 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
357 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10,
358 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0,
359 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xab, 0xcd};
360
361 pldm_firmware_device_id_record deviceIdRecHeader{};
362 variable_field applicableComponents{};
363 variable_field outCompImageSetVersionStr{};
364 variable_field recordDescriptors{};
365 variable_field outFwDevicePkgData{};
366
367 auto rc = decode_firmware_device_id_record(
368 record.data(), record.size(), componentBitmapBitLength,
369 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
370 &recordDescriptors, &outFwDevicePkgData);
371
Andrew Jefferybacbbac2025-03-12 04:02:18 +0000372 ASSERT_EQ(rc, PLDM_SUCCESS);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930373 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
374 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
375 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
376 deviceUpdateFlag);
377 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
378 PLDM_STR_TYPE_ASCII);
379 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
380 imageSetVersionStr.size());
381 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, fwDevicePkgDataLen);
382
383 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
384 EXPECT_EQ(true,
385 std::equal(applicableComponents.ptr,
386 applicableComponents.ptr + applicableComponents.length,
387 applicableComponentsBitfield.begin(),
388 applicableComponentsBitfield.end()));
389
390 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
391 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930392 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930393 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
394 outCompImageSetVersionStr.length);
395 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
396
397 uint16_t descriptorType = 0;
398 uint16_t descriptorLen = 0;
399 variable_field descriptorData{};
400 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
401 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
402 recordDescriptors.length,
403 &descriptorType, &descriptorData);
404 EXPECT_EQ(rc, PLDM_SUCCESS);
405 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
406 sizeof(descriptorLen) +
407 descriptorData.length);
408 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
409 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
410 EXPECT_EQ(true, std::equal(descriptorData.ptr,
411 descriptorData.ptr + descriptorData.length,
412 uuid.begin(), uuid.end()));
413
414 EXPECT_EQ(outFwDevicePkgData.length, fwDevicePkgData.size());
415 EXPECT_EQ(true,
416 std::equal(outFwDevicePkgData.ptr,
417 outFwDevicePkgData.ptr + outFwDevicePkgData.length,
418 fwDevicePkgData.begin(), fwDevicePkgData.end()));
419}
420
421TEST(DecodeFirmwareDeviceIdRecord, goodPathNofwDevicePkgData)
422{
423 constexpr uint8_t descriptorCount = 1;
424 // Continue component updates after failure
425 constexpr std::bitset<32> deviceUpdateFlag{1};
426 constexpr uint16_t componentBitmapBitLength = 8;
427 // Applicable Components - 1,2
428 std::vector<std::bitset<8>> applicableComponentsBitfield{0x03};
429 // ComponentImageSetVersionString
430 constexpr std::string_view imageSetVersionStr{"VersionString1"};
431 // Initial descriptor - UUID
432 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
433 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
434 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
435 constexpr uint16_t fwDevicePkgDataLen = 0;
436
437 // Size of the firmware device ID record
438 constexpr uint16_t recordLen =
439 sizeof(pldm_firmware_device_id_record) +
440 (componentBitmapBitLength / PLDM_FWUP_COMPONENT_BITMAP_MULTIPLE) +
441 imageSetVersionStr.size() +
442 sizeof(pldm_descriptor_tlv().descriptor_type) +
443 sizeof(pldm_descriptor_tlv().descriptor_length) + uuid.size() +
444 fwDevicePkgDataLen;
445 // Firmware device ID record
446 constexpr std::array<uint8_t, recordLen> record{
447 0x2e, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x03,
448 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e,
449 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d,
450 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
451
452 pldm_firmware_device_id_record deviceIdRecHeader{};
453 variable_field applicableComponents{};
454 variable_field outCompImageSetVersionStr{};
455 variable_field recordDescriptors{};
456 variable_field outFwDevicePkgData{};
457
458 auto rc = decode_firmware_device_id_record(
459 record.data(), record.size(), componentBitmapBitLength,
460 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
461 &recordDescriptors, &outFwDevicePkgData);
462
463 EXPECT_EQ(rc, PLDM_SUCCESS);
464 EXPECT_EQ(deviceIdRecHeader.record_length, recordLen);
465 EXPECT_EQ(deviceIdRecHeader.descriptor_count, descriptorCount);
466 EXPECT_EQ(deviceIdRecHeader.device_update_option_flags.value,
467 deviceUpdateFlag);
468 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_type,
469 PLDM_STR_TYPE_ASCII);
470 EXPECT_EQ(deviceIdRecHeader.comp_image_set_version_string_length,
471 imageSetVersionStr.size());
472 EXPECT_EQ(deviceIdRecHeader.fw_device_pkg_data_length, 0);
473
474 EXPECT_EQ(applicableComponents.length, applicableComponentsBitfield.size());
475 EXPECT_EQ(true,
476 std::equal(applicableComponents.ptr,
477 applicableComponents.ptr + applicableComponents.length,
478 applicableComponentsBitfield.begin(),
479 applicableComponentsBitfield.end()));
480
481 EXPECT_EQ(outCompImageSetVersionStr.length, imageSetVersionStr.size());
482 std::string compImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930483 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930484 reinterpret_cast<const char*>(outCompImageSetVersionStr.ptr),
485 outCompImageSetVersionStr.length);
486 EXPECT_EQ(compImageSetVersionStr, imageSetVersionStr);
487
488 uint16_t descriptorType = 0;
489 uint16_t descriptorLen = 0;
490 variable_field descriptorData{};
491 // DescriptorCount is 1, so decode_descriptor_type_length_value called once
492 rc = decode_descriptor_type_length_value(recordDescriptors.ptr,
493 recordDescriptors.length,
494 &descriptorType, &descriptorData);
495 EXPECT_EQ(rc, PLDM_SUCCESS);
496 EXPECT_EQ(recordDescriptors.length, sizeof(descriptorType) +
497 sizeof(descriptorLen) +
498 descriptorData.length);
499 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
500 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
501 EXPECT_EQ(true, std::equal(descriptorData.ptr,
502 descriptorData.ptr + descriptorData.length,
503 uuid.begin(), uuid.end()));
504
505 EXPECT_EQ(outFwDevicePkgData.ptr, nullptr);
506 EXPECT_EQ(outFwDevicePkgData.length, 0);
507}
508
509TEST(DecodeFirmwareDeviceIdRecord, ErrorPaths)
510{
Andrew Jeffery9c766792022-08-10 23:12:49 +0930511 // Invalid ComponentImageSetVersionStringType
Andrew Jeffery92c32362025-03-10 03:36:46 +0000512 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
513 0x00, 0x06, 0x0e, 0x00, 0x00};
514 constexpr uint16_t componentBitmapBitLength = 8;
515
516 pldm_firmware_device_id_record deviceIdRecHeader{};
517 variable_field outCompImageSetVersionStr{};
518 variable_field applicableComponents{};
519 variable_field outFwDevicePkgData{};
520 variable_field recordDescriptors{};
521 int rc = 0;
522
523 rc = decode_firmware_device_id_record(
524 nullptr, rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
525 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
526 &outFwDevicePkgData);
527 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
528
529 rc = decode_firmware_device_id_record(
530 rec.data(), rec.size(), componentBitmapBitLength, nullptr,
531 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
532 &outFwDevicePkgData);
533 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
534
535 rc = decode_firmware_device_id_record(
536 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
537 nullptr, &outCompImageSetVersionStr, &recordDescriptors,
538 &outFwDevicePkgData);
539 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
540
541 rc = decode_firmware_device_id_record(
542 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
543 &applicableComponents, nullptr, &recordDescriptors,
544 &outFwDevicePkgData);
545 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
546
547 rc = decode_firmware_device_id_record(
548 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
549 &applicableComponents, &outCompImageSetVersionStr, nullptr,
550 &outFwDevicePkgData);
551 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
552
553 rc = decode_firmware_device_id_record(
554 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
555 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
556 nullptr);
557 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
558
559 rc = decode_firmware_device_id_record(
560 rec.data(), rec.size() - 1, componentBitmapBitLength,
561 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
562 &recordDescriptors, &outFwDevicePkgData);
563 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
564
565 rc = decode_firmware_device_id_record(
566 rec.data(), rec.size(), componentBitmapBitLength + 1,
567 &deviceIdRecHeader, &applicableComponents, &outCompImageSetVersionStr,
568 &recordDescriptors, &outFwDevicePkgData);
569 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
570
571 rc = decode_firmware_device_id_record(
572 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
573 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
574 &outFwDevicePkgData);
575 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
576}
577
578TEST(DecodeFirmwareDeviceIdRecord, invalidComponentImageSetVersionStringLength)
579{
580 constexpr std::array<uint8_t, 11> rec{0x0b, 0x00, 0x01, 0x01, 0x00, 0x00,
581 0x00, 0x01, 0x00, 0x00, 0x00};
582 constexpr uint16_t componentBitmapBitLength = 8;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930583
584 int rc = 0;
585 pldm_firmware_device_id_record deviceIdRecHeader{};
586 variable_field applicableComponents{};
587 variable_field outCompImageSetVersionStr{};
588 variable_field recordDescriptors{};
589 variable_field outFwDevicePkgData{};
590
591 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000592 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
593 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930594 &outFwDevicePkgData);
595 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000596}
597
598TEST(DecodeFirmwareDeviceIdRecord, shortBuffer)
599{
600 constexpr std::array<uint8_t, 11> rec{0x2e, 0x00, 0x01, 0x01, 0x00, 0x00,
601 0x00, 0x01, 0x0e, 0x00, 0x00};
602 constexpr uint16_t componentBitmapBitLength = 8;
603
604 pldm_firmware_device_id_record deviceIdRecHeader{};
605 variable_field outCompImageSetVersionStr{};
606 variable_field applicableComponents{};
607 variable_field outFwDevicePkgData{};
608 variable_field recordDescriptors{};
609 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930610
611 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000612 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
613 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
614 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930615 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000616}
617
618TEST(DecodeFirmwareDeviceIdRecord, recordLengthMismatch)
619{
620 constexpr std::array<uint8_t, 11> rec{0x15, 0x00, 0x01, 0x01, 0x00, 0x00,
621 0x00, 0x01, 0x0e, 0x02, 0x00};
622 constexpr uint16_t componentBitmapBitLength = 8;
623
624 pldm_firmware_device_id_record deviceIdRecHeader{};
625 variable_field outCompImageSetVersionStr{};
626 variable_field applicableComponents{};
627 variable_field outFwDevicePkgData{};
628 variable_field recordDescriptors{};
629 int rc = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930630
631 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000632 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
633 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
634 &outFwDevicePkgData);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930635 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery92c32362025-03-10 03:36:46 +0000636}
Andrew Jeffery9c766792022-08-10 23:12:49 +0930637
Andrew Jeffery92c32362025-03-10 03:36:46 +0000638TEST(DecodeFirmwareDeviceIdRecord, invalidFirmwareDevicePackageDataLength)
639{
640 constexpr std::array<uint8_t, 49> rec{
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800641 0x31, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e,
642 // FirmwareDevicePackageDataLength = 0xffff
643 0xff, 0xff,
644 //
645 0x93, 0x01, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72,
646 0x69, 0x6e, 0x67, 0x31, 0x02, 0x00, 0x10, 0x00, 0x12, 0x44, 0xd2, 0x64,
647 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b,
648 0xab, 0xcd};
Andrew Jeffery92c32362025-03-10 03:36:46 +0000649 constexpr uint16_t componentBitmapBitLength = 8;
650
651 pldm_firmware_device_id_record deviceIdRecHeader{};
652 variable_field outCompImageSetVersionStr{};
653 variable_field applicableComponents{};
654 variable_field outFwDevicePkgData{};
655 variable_field recordDescriptors{};
656 int rc = 0;
657
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800658 rc = decode_firmware_device_id_record(
Andrew Jeffery92c32362025-03-10 03:36:46 +0000659 rec.data(), rec.size(), componentBitmapBitLength, &deviceIdRecHeader,
660 &applicableComponents, &outCompImageSetVersionStr, &recordDescriptors,
661 &outFwDevicePkgData);
Matt Johnstonc4d1c8b2024-12-18 11:16:55 +0800662 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930663}
664
665TEST(DecodeDescriptors, goodPath3Descriptors)
666{
667 // In the descriptor data there are 3 descriptor entries
668 // 1) IANA enterprise ID
669 constexpr std::array<uint8_t, PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH> iana{
670 0x0a, 0x0b, 0x0c, 0xd};
671 // 2) UUID
672 constexpr std::array<uint8_t, PLDM_FWUP_UUID_LENGTH> uuid{
673 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18,
674 0xa0, 0x30, 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b};
675 // 3) Vendor Defined
676 constexpr std::string_view vendorTitle{"OpenBMC"};
677 constexpr size_t vendorDescriptorLen = 2;
678 constexpr std::array<uint8_t, vendorDescriptorLen> vendorDescriptorData{
679 0x01, 0x02};
680
681 constexpr size_t vendorDefinedDescriptorLen =
682 sizeof(pldm_vendor_defined_descriptor_title_data()
683 .vendor_defined_descriptor_title_str_type) +
684 sizeof(pldm_vendor_defined_descriptor_title_data()
685 .vendor_defined_descriptor_title_str_len) +
686 vendorTitle.size() + vendorDescriptorData.size();
687
688 constexpr size_t descriptorsLength =
689 3 * (sizeof(pldm_descriptor_tlv().descriptor_type) +
690 sizeof(pldm_descriptor_tlv().descriptor_length)) +
691 iana.size() + uuid.size() + vendorDefinedDescriptorLen;
692
693 constexpr std::array<uint8_t, descriptorsLength> descriptors{
694 0x01, 0x00, 0x04, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x02, 0x00, 0x10,
695 0x00, 0x12, 0x44, 0xd2, 0x64, 0x8d, 0x7d, 0x47, 0x18, 0xa0, 0x30,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600696 0xfc, 0x8a, 0x56, 0x58, 0x7d, 0x5b, 0xff, 0xff, 0x0b, 0x00, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +0930697 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43, 0x01, 0x02};
698
699 size_t descriptorCount = 1;
700 size_t descriptorsRemainingLength = descriptorsLength;
701 int rc = 0;
702
703 while (descriptorsRemainingLength && (descriptorCount <= 3))
704 {
705 uint16_t descriptorType = 0;
706 uint16_t descriptorLen = 0;
707 variable_field descriptorData{};
708
709 rc = decode_descriptor_type_length_value(
710 descriptors.data() + descriptorsLength - descriptorsRemainingLength,
711 descriptorsRemainingLength, &descriptorType, &descriptorData);
712 EXPECT_EQ(rc, PLDM_SUCCESS);
713
714 if (descriptorCount == 1)
715 {
716 EXPECT_EQ(descriptorType, PLDM_FWUP_IANA_ENTERPRISE_ID);
717 EXPECT_EQ(descriptorData.length,
718 PLDM_FWUP_IANA_ENTERPRISE_ID_LENGTH);
719 EXPECT_EQ(true,
720 std::equal(descriptorData.ptr,
721 descriptorData.ptr + descriptorData.length,
722 iana.begin(), iana.end()));
723 }
724 else if (descriptorCount == 2)
725 {
726 EXPECT_EQ(descriptorType, PLDM_FWUP_UUID);
727 EXPECT_EQ(descriptorData.length, PLDM_FWUP_UUID_LENGTH);
728 EXPECT_EQ(true,
729 std::equal(descriptorData.ptr,
730 descriptorData.ptr + descriptorData.length,
731 uuid.begin(), uuid.end()));
732 }
733 else if (descriptorCount == 3)
734 {
735 EXPECT_EQ(descriptorType, PLDM_FWUP_VENDOR_DEFINED);
736 EXPECT_EQ(descriptorData.length, vendorDefinedDescriptorLen);
737
738 uint8_t descriptorTitleStrType = 0;
739 variable_field descriptorTitleStr{};
740 variable_field vendorDefinedDescriptorData{};
741
742 rc = decode_vendor_defined_descriptor_value(
743 descriptorData.ptr, descriptorData.length,
744 &descriptorTitleStrType, &descriptorTitleStr,
745 &vendorDefinedDescriptorData);
746 EXPECT_EQ(rc, PLDM_SUCCESS);
747
748 EXPECT_EQ(descriptorTitleStrType, PLDM_STR_TYPE_ASCII);
749 EXPECT_EQ(descriptorTitleStr.length, vendorTitle.size());
750 std::string vendorTitleStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930751 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930752 reinterpret_cast<const char*>(descriptorTitleStr.ptr),
753 descriptorTitleStr.length);
754 EXPECT_EQ(vendorTitleStr, vendorTitle);
755
756 EXPECT_EQ(vendorDefinedDescriptorData.length,
757 vendorDescriptorData.size());
758 EXPECT_EQ(true, std::equal(vendorDefinedDescriptorData.ptr,
759 vendorDefinedDescriptorData.ptr +
760 vendorDefinedDescriptorData.length,
761 vendorDescriptorData.begin(),
762 vendorDescriptorData.end()));
763 }
764
765 descriptorsRemainingLength -= sizeof(descriptorType) +
766 sizeof(descriptorLen) +
767 descriptorData.length;
768 descriptorCount++;
769 }
770}
771
772TEST(DecodeDescriptors, errorPathDecodeDescriptorTLV)
773{
774 int rc = 0;
775 // IANA Enterprise ID descriptor length incorrect
776 constexpr std::array<uint8_t, 7> invalidIANADescriptor1{
777 0x01, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c};
778 uint16_t descriptorType = 0;
779 variable_field descriptorData{};
780
781 rc = decode_descriptor_type_length_value(nullptr,
782 invalidIANADescriptor1.size(),
783 &descriptorType, &descriptorData);
784 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
785
786 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
787 invalidIANADescriptor1.size(),
788 nullptr, &descriptorData);
789 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
790
791 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
792 invalidIANADescriptor1.size(),
793 &descriptorType, nullptr);
794 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
795
796 rc = decode_descriptor_type_length_value(
797 invalidIANADescriptor1.data(), PLDM_FWUP_DEVICE_DESCRIPTOR_MIN_LEN - 1,
798 &descriptorType, &descriptorData);
799 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
800
801 rc = decode_descriptor_type_length_value(invalidIANADescriptor1.data(),
802 invalidIANADescriptor1.size(),
803 &descriptorType, &descriptorData);
Andrew Jeffery779e9db2025-02-21 12:14:28 +1030804 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jeffery9c766792022-08-10 23:12:49 +0930805
806 // IANA Enterprise ID descriptor data less than length
807 std::array<uint8_t, 7> invalidIANADescriptor2{0x01, 0x00, 0x04, 0x00,
808 0x0a, 0x0b, 0x0c};
809 rc = decode_descriptor_type_length_value(invalidIANADescriptor2.data(),
810 invalidIANADescriptor2.size(),
811 &descriptorType, &descriptorData);
812 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
813}
814
815TEST(DecodeDescriptors, errorPathVendorDefinedDescriptor)
816{
817 int rc = 0;
818 // VendorDefinedDescriptorTitleStringType is invalid
819 constexpr std::array<uint8_t, 9> invalidVendorDescriptor1{
820 0x06, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
821 uint8_t descriptorStringType = 0;
822 variable_field descriptorTitleStr{};
823 variable_field vendorDefinedDescriptorData{};
824
825 rc = decode_vendor_defined_descriptor_value(
826 nullptr, invalidVendorDescriptor1.size(), &descriptorStringType,
827 &descriptorTitleStr, &vendorDefinedDescriptorData);
828 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
829
830 rc = decode_vendor_defined_descriptor_value(
831 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
832 &descriptorStringType, &descriptorTitleStr,
833 &vendorDefinedDescriptorData);
834 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
835
836 rc = decode_vendor_defined_descriptor_value(
837 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
838 nullptr, &descriptorTitleStr, &vendorDefinedDescriptorData);
839 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
840
841 rc = decode_vendor_defined_descriptor_value(
842 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
843 &descriptorStringType, nullptr, &vendorDefinedDescriptorData);
844 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
845
846 rc = decode_vendor_defined_descriptor_value(
847 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
848 &descriptorStringType, &descriptorTitleStr, nullptr);
849 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
850
851 rc = decode_vendor_defined_descriptor_value(
852 invalidVendorDescriptor1.data(),
853 sizeof(pldm_vendor_defined_descriptor_title_data) - 1,
854 &descriptorStringType, &descriptorTitleStr,
855 &vendorDefinedDescriptorData);
856 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
857
858 rc = decode_vendor_defined_descriptor_value(
859 invalidVendorDescriptor1.data(), invalidVendorDescriptor1.size(),
860 &descriptorStringType, &descriptorTitleStr,
861 &vendorDefinedDescriptorData);
862 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
863
864 // VendorDefinedDescriptorTitleStringLength is 0
865 std::array<uint8_t, 9> invalidVendorDescriptor2{
866 0x01, 0x00, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
867 rc = decode_vendor_defined_descriptor_value(
868 invalidVendorDescriptor2.data(), invalidVendorDescriptor2.size(),
869 &descriptorStringType, &descriptorTitleStr,
870 &vendorDefinedDescriptorData);
871 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
872
873 // VendorDefinedDescriptorData not present in the data
874 std::array<uint8_t, 9> invalidVendorDescriptor3{
875 0x01, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x42, 0x4d, 0x43};
876 rc = decode_vendor_defined_descriptor_value(
877 invalidVendorDescriptor3.data(), invalidVendorDescriptor3.size(),
878 &descriptorStringType, &descriptorTitleStr,
879 &vendorDefinedDescriptorData);
880 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
881}
882
883TEST(DecodeComponentImageInfo, goodPath)
884{
885 // Firmware
886 constexpr uint16_t compClassification = 16;
887 constexpr uint16_t compIdentifier = 300;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600888 constexpr uint32_t compComparisonStamp = 0xffffffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +0930889 // Force update
890 constexpr std::bitset<16> compOptions{1};
891 // System reboot[Bit position 3] & Medium-specific reset[Bit position 2]
892 constexpr std::bitset<16> reqCompActivationMethod{0x0c};
893 // Random ComponentLocationOffset
894 constexpr uint32_t compLocOffset = 357;
895 // Random ComponentSize
896 constexpr uint32_t compSize = 27;
897 // ComponentVersionString
898 constexpr std::string_view compVersionStr{"VersionString1"};
899 constexpr size_t compImageInfoSize =
900 sizeof(pldm_component_image_information) + compVersionStr.size();
901
902 constexpr std::array<uint8_t, compImageInfoSize> compImageInfo{
903 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
904 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
905 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
906 pldm_component_image_information outCompImageInfo{};
907 variable_field outCompVersionStr{};
908
909 auto rc =
910 decode_pldm_comp_image_info(compImageInfo.data(), compImageInfo.size(),
911 &outCompImageInfo, &outCompVersionStr);
912
913 EXPECT_EQ(rc, PLDM_SUCCESS);
914 EXPECT_EQ(outCompImageInfo.comp_classification, compClassification);
915 EXPECT_EQ(outCompImageInfo.comp_identifier, compIdentifier);
916 EXPECT_EQ(outCompImageInfo.comp_comparison_stamp, compComparisonStamp);
917 EXPECT_EQ(outCompImageInfo.comp_options.value, compOptions);
918 EXPECT_EQ(outCompImageInfo.requested_comp_activation_method.value,
919 reqCompActivationMethod);
920 EXPECT_EQ(outCompImageInfo.comp_location_offset, compLocOffset);
921 EXPECT_EQ(outCompImageInfo.comp_size, compSize);
922 EXPECT_EQ(outCompImageInfo.comp_version_string_type, PLDM_STR_TYPE_ASCII);
923 EXPECT_EQ(outCompImageInfo.comp_version_string_length,
924 compVersionStr.size());
925
926 EXPECT_EQ(outCompVersionStr.length,
927 outCompImageInfo.comp_version_string_length);
928 std::string componentVersionString(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +0930929 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +0930930 reinterpret_cast<const char*>(outCompVersionStr.ptr),
931 outCompVersionStr.length);
932 EXPECT_EQ(componentVersionString, compVersionStr);
933}
934
935TEST(DecodeComponentImageInfo, errorPaths)
936{
937 int rc = 0;
938 // ComponentVersionString
939 constexpr std::string_view compVersionStr{"VersionString1"};
940 constexpr size_t compImageInfoSize =
941 sizeof(pldm_component_image_information) + compVersionStr.size();
942 // Invalid ComponentVersionStringType - 0x06
943 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo1{
944 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
945 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x56, 0x65,
946 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
947 pldm_component_image_information outCompImageInfo{};
948 variable_field outCompVersionStr{};
949
950 rc = decode_pldm_comp_image_info(nullptr, invalidCompImageInfo1.size(),
951 &outCompImageInfo, &outCompVersionStr);
952 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
953
954 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
955 invalidCompImageInfo1.size(), nullptr,
956 &outCompVersionStr);
957 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
958
959 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
960 invalidCompImageInfo1.size(),
961 &outCompImageInfo, nullptr);
962 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
963
964 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
965 sizeof(pldm_component_image_information) -
966 1,
967 &outCompImageInfo, &outCompVersionStr);
968 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
969
970 rc = decode_pldm_comp_image_info(invalidCompImageInfo1.data(),
971 invalidCompImageInfo1.size(),
972 &outCompImageInfo, &outCompVersionStr);
973 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
974
975 // Invalid ComponentVersionStringLength - 0x00
976 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo2{
977 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
978 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, 0x65,
979 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
980 rc = decode_pldm_comp_image_info(invalidCompImageInfo2.data(),
981 invalidCompImageInfo2.size(),
982 &outCompImageInfo, &outCompVersionStr);
983 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
984
985 // Use Component Comparison Stamp is not set, but ComponentComparisonStamp
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -0600986 // is not 0xffffffff
Andrew Jeffery9c766792022-08-10 23:12:49 +0930987 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo3{
988 0x10, 0x00, 0x2c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00,
989 0x65, 0x01, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
990 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
991
992 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
993 invalidCompImageInfo3.size() - 1,
994 &outCompImageInfo, &outCompVersionStr);
995 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
996
997 rc = decode_pldm_comp_image_info(invalidCompImageInfo3.data(),
998 invalidCompImageInfo3.size(),
999 &outCompImageInfo, &outCompVersionStr);
1000 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1001
1002 // Invalid ComponentLocationOffset - 0
1003 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo4{
1004 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1005 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1006 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1007 rc = decode_pldm_comp_image_info(invalidCompImageInfo4.data(),
1008 invalidCompImageInfo4.size(),
1009 &outCompImageInfo, &outCompVersionStr);
1010 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1011
1012 // Invalid ComponentSize - 0
1013 constexpr std::array<uint8_t, compImageInfoSize> invalidCompImageInfo5{
1014 0x10, 0x00, 0x2c, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x0c, 0x00,
1015 0x65, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x56, 0x65,
1016 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31};
1017 rc = decode_pldm_comp_image_info(invalidCompImageInfo5.data(),
1018 invalidCompImageInfo5.size(),
1019 &outCompImageInfo, &outCompVersionStr);
1020 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1021}
1022
1023TEST(QueryDeviceIdentifiers, goodPathEncodeRequest)
1024{
1025 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301026 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301027 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1028
1029 uint8_t instanceId = 0x01;
1030
1031 auto rc = encode_query_device_identifiers_req(
1032 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, requestPtr);
1033 EXPECT_EQ(rc, PLDM_SUCCESS);
1034 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1035 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1036 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1037 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DEVICE_IDENTIFIERS);
1038}
1039
1040TEST(QueryDeviceIdentifiers, goodPathDecodeResponse)
1041{
1042 // descriptorDataLen is not fixed here taking it as 6
1043 constexpr uint8_t descriptorDataLen = 6;
1044 std::array<uint8_t, hdrSize +
1045 sizeof(struct pldm_query_device_identifiers_resp) +
1046 descriptorDataLen>
1047 responseMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301048 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301049 auto inResp = reinterpret_cast<struct pldm_query_device_identifiers_resp*>(
1050 responseMsg.data() + hdrSize);
1051
1052 inResp->completion_code = PLDM_SUCCESS;
1053 inResp->device_identifiers_len = htole32(descriptorDataLen);
1054 inResp->descriptor_count = 1;
1055
1056 // filling descriptor data
1057 std::fill_n(responseMsg.data() + hdrSize +
1058 sizeof(struct pldm_query_device_identifiers_resp),
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001059 descriptorDataLen, 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301060
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301061 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301062 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1063 uint8_t completionCode = PLDM_SUCCESS;
1064 uint32_t deviceIdentifiersLen = 0;
1065 uint8_t descriptorCount = 0;
1066 uint8_t* outDescriptorData = nullptr;
1067
1068 auto rc = decode_query_device_identifiers_resp(
1069 response, responseMsg.size() - hdrSize, &completionCode,
1070 &deviceIdentifiersLen, &descriptorCount, &outDescriptorData);
1071
1072 EXPECT_EQ(rc, PLDM_SUCCESS);
1073 EXPECT_EQ(completionCode, PLDM_SUCCESS);
1074 EXPECT_EQ(deviceIdentifiersLen, inResp->device_identifiers_len);
1075 EXPECT_EQ(descriptorCount, inResp->descriptor_count);
1076 EXPECT_EQ(true,
1077 std::equal(outDescriptorData,
1078 outDescriptorData + deviceIdentifiersLen,
1079 responseMsg.begin() + hdrSize +
1080 sizeof(struct pldm_query_device_identifiers_resp),
1081 responseMsg.end()));
1082}
1083
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001084#ifdef LIBPLDM_API_TESTING
1085TEST(QueryDeviceIdentifiers, goodPathEncodeResponse)
1086{
1087 int rc;
1088 PLDM_MSG_DEFINE_P(enc, 1000);
1089 size_t enc_payload_len = 1000;
1090 pldm_descriptor check_desc[] = {
1091 {
1092 .descriptor_type = PLDM_FWUP_IANA_ENTERPRISE_ID,
1093 .descriptor_length = 4,
1094 .descriptor_data = "a123",
1095 },
1096 {
1097 .descriptor_type = PLDM_FWUP_VENDOR_DEFINED,
1098 .descriptor_length = 3,
1099 .descriptor_data = "987",
1100 },
1101 };
1102 rc = encode_query_device_identifiers_resp(FIXED_INSTANCE_ID, 2, check_desc,
1103 enc, &enc_payload_len);
1104 EXPECT_EQ(rc, 0);
1105 EXPECT_THAT(std::span<uint8_t>(enc_buf + hdrSize, enc_payload_len),
1106 ElementsAreArray<uint8_t>({
1107 // completion code
1108 0x00,
1109 // device identifiers length = 15
1110 0x0f,
1111 0x00,
1112 0x00,
1113 0x00,
1114 // descriptor count
1115 0x02,
1116 // desc 0
1117 0x01,
1118 0x00,
1119 0x04,
1120 0x00,
1121 0x61,
1122 0x31,
1123 0x32,
1124 0x33,
1125 // desc 1
1126 0xff,
1127 0xff,
1128 0x03,
1129 0x00,
1130 0x39,
1131 0x38,
1132 0x37,
1133 }));
1134
1135 check_response(enc, PLDM_QUERY_DEVICE_IDENTIFIERS);
1136}
1137#endif
1138
Andrew Jeffery9c766792022-08-10 23:12:49 +09301139TEST(GetFirmwareParameters, goodPathEncodeRequest)
1140{
1141 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301142 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301143 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1144 uint8_t instanceId = 0x01;
1145
1146 auto rc = encode_get_firmware_parameters_req(
1147 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, requestPtr);
1148 EXPECT_EQ(rc, PLDM_SUCCESS);
1149 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1150 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1151 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1152 EXPECT_EQ(requestPtr->hdr.command, PLDM_GET_FIRMWARE_PARAMETERS);
1153}
1154
1155TEST(GetFirmwareParameters, decodeResponse)
1156{
1157 // CapabilitiesDuringUpdate of the firmware device
1158 // Firmware device downgrade restrictions [Bit position 8] &
1159 // Firmware Device Partial Updates [Bit position 3]
1160 constexpr std::bitset<32> fdCapabilities{0x00000104};
1161 constexpr uint16_t compCount = 1;
1162 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1163 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1164
1165 // constexpr uint16_t compClassification = 16;
1166 // constexpr uint16_t compIdentifier = 300;
1167 // constexpr uint8_t compClassificationIndex = 20;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001168 // constexpr uint32_t activeCompComparisonStamp = 0xabcdefab;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301169 // constexpr std::array<uint8_t, 8> activeComponentReleaseData = {
1170 // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
1171 // constexpr uint32_t pendingCompComparisonStamp = 0x12345678;
1172 // constexpr std::array<uint8_t, 8> pendingComponentReleaseData = {
1173 // 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
1174 constexpr std::string_view activeCompVersion{"VersionString3"};
1175 constexpr std::string_view pendingCompVersion{"VersionString4"};
Andrew Jeffery9c766792022-08-10 23:12:49 +09301176
1177 constexpr size_t compParamTableSize =
1178 sizeof(pldm_component_parameter_entry) + activeCompVersion.size() +
1179 pendingCompVersion.size();
1180
1181 constexpr std::array<uint8_t, compParamTableSize> compParamTable{
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001182 0x10, 0x00, 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301183 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1184 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00, 0x02,
1185 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74,
1186 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1187 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1188
1189 constexpr size_t getFwParamsPayloadLen =
1190 sizeof(pldm_get_firmware_parameters_resp) +
1191 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size() +
1192 compParamTableSize;
1193
1194 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1195 getFwParamsResponse{
1196 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01,
1197 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1198 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1199 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32, 0x10, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001200 0x2c, 0x01, 0x14, 0xab, 0xef, 0xcd, 0xab, 0x01, 0x0e, 0x01, 0x02,
Andrew Jeffery9c766792022-08-10 23:12:49 +09301201 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x78, 0x56, 0x34, 0x12, 0x01,
1202 0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x12, 0x00,
1203 0x02, 0x00, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1204 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x33, 0x56, 0x65, 0x72, 0x73,
1205 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x34};
1206
1207 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301208 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301209 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1210 pldm_get_firmware_parameters_resp outResp{};
1211 variable_field outActiveCompImageSetVersion{};
1212 variable_field outPendingCompImageSetVersion{};
1213 variable_field outCompParameterTable{};
1214
1215 auto rc = decode_get_firmware_parameters_resp(
1216 responseMsg, getFwParamsPayloadLen, &outResp,
1217 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1218 &outCompParameterTable);
1219
1220 EXPECT_EQ(rc, PLDM_SUCCESS);
1221 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1222 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1223 EXPECT_EQ(outResp.comp_count, compCount);
1224 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1225 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1226 activeCompImageSetVersion.size());
1227 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1228 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1229 pendingCompImageSetVersion.size());
1230 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301231 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301232 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1233 outActiveCompImageSetVersion.length);
1234 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1235 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301236 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301237 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1238 outPendingCompImageSetVersion.length);
1239 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1240 EXPECT_EQ(outCompParameterTable.length, compParamTableSize);
1241 EXPECT_EQ(true, std::equal(outCompParameterTable.ptr,
1242 outCompParameterTable.ptr +
1243 outCompParameterTable.length,
1244 compParamTable.begin(), compParamTable.end()));
1245}
1246
1247TEST(GetFirmwareParameters, decodeResponseZeroCompCount)
1248{
1249 // CapabilitiesDuringUpdate of the firmware device
1250 // FD Host Functionality during Firmware Update [Bit position 2] &
1251 // Component Update Failure Retry Capability [Bit position 1]
1252 constexpr std::bitset<32> fdCapabilities{0x06};
1253 constexpr uint16_t compCount = 0;
1254 constexpr std::string_view activeCompImageSetVersion{"VersionString1"};
1255 constexpr std::string_view pendingCompImageSetVersion{"VersionString2"};
1256
1257 constexpr size_t getFwParamsPayloadLen =
1258 sizeof(pldm_get_firmware_parameters_resp) +
1259 activeCompImageSetVersion.size() + pendingCompImageSetVersion.size();
1260
1261 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1262 getFwParamsResponse{
1263 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
1264 0x0e, 0x01, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53,
1265 0x74, 0x72, 0x69, 0x6e, 0x67, 0x31, 0x56, 0x65, 0x72, 0x73, 0x69,
1266 0x6f, 0x6e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x32};
1267
1268 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301269 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301270 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1271 pldm_get_firmware_parameters_resp outResp{};
1272 variable_field outActiveCompImageSetVersion{};
1273 variable_field outPendingCompImageSetVersion{};
1274 variable_field outCompParameterTable{};
1275
1276 auto rc = decode_get_firmware_parameters_resp(
1277 responseMsg, getFwParamsPayloadLen, &outResp,
1278 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1279 &outCompParameterTable);
1280
1281 EXPECT_EQ(rc, PLDM_SUCCESS);
1282 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1283 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1284 EXPECT_EQ(outResp.comp_count, compCount);
1285 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1286 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1287 activeCompImageSetVersion.size());
1288 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1289 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len,
1290 pendingCompImageSetVersion.size());
1291 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301292 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301293 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1294 outActiveCompImageSetVersion.length);
1295 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1296 std::string pendingCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301297 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301298 reinterpret_cast<const char*>(outPendingCompImageSetVersion.ptr),
1299 outPendingCompImageSetVersion.length);
1300 EXPECT_EQ(pendingCompImageSetVersionStr, pendingCompImageSetVersion);
1301 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1302 EXPECT_EQ(outCompParameterTable.length, 0);
1303}
1304
1305TEST(GetFirmwareParameters,
1306 decodeResponseNoPendingCompImageVersionStrZeroCompCount)
1307{
1308 // CapabilitiesDuringUpdate of the firmware device
1309 // FD Host Functionality during Firmware Update [Bit position 2] &
1310 // Component Update Failure Retry Capability [Bit position 1]
1311 constexpr std::bitset<32> fdCapabilities{0x06};
1312 constexpr uint16_t compCount = 0;
1313 constexpr std::string_view activeCompImageSetVersion{"VersionString"};
1314
1315 constexpr size_t getFwParamsPayloadLen =
1316 sizeof(pldm_get_firmware_parameters_resp) +
1317 activeCompImageSetVersion.size();
1318
1319 constexpr std::array<uint8_t, hdrSize + getFwParamsPayloadLen>
1320 getFwParamsResponse{0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1321 0x00, 0x00, 0x00, 0x01, 0x0d, 0x00, 0x00,
1322 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
1323 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67};
1324
1325 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301326 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301327 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1328 pldm_get_firmware_parameters_resp outResp{};
1329 variable_field outActiveCompImageSetVersion{};
1330 variable_field outPendingCompImageSetVersion{};
1331 variable_field outCompParameterTable{};
1332
1333 auto rc = decode_get_firmware_parameters_resp(
1334 responseMsg, getFwParamsPayloadLen, &outResp,
1335 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1336 &outCompParameterTable);
1337
1338 EXPECT_EQ(rc, PLDM_SUCCESS);
1339 EXPECT_EQ(outResp.completion_code, PLDM_SUCCESS);
1340 EXPECT_EQ(outResp.capabilities_during_update.value, fdCapabilities);
1341 EXPECT_EQ(outResp.comp_count, compCount);
1342 EXPECT_EQ(outResp.active_comp_image_set_ver_str_type, PLDM_STR_TYPE_ASCII);
1343 EXPECT_EQ(outResp.active_comp_image_set_ver_str_len,
1344 activeCompImageSetVersion.size());
1345 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_type,
1346 PLDM_STR_TYPE_UNKNOWN);
1347 EXPECT_EQ(outResp.pending_comp_image_set_ver_str_len, 0);
1348 std::string activeCompImageSetVersionStr(
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301349 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301350 reinterpret_cast<const char*>(outActiveCompImageSetVersion.ptr),
1351 outActiveCompImageSetVersion.length);
1352 EXPECT_EQ(activeCompImageSetVersionStr, activeCompImageSetVersion);
1353 EXPECT_EQ(outPendingCompImageSetVersion.ptr, nullptr);
1354 EXPECT_EQ(outPendingCompImageSetVersion.length, 0);
1355 EXPECT_EQ(outCompParameterTable.ptr, nullptr);
1356 EXPECT_EQ(outCompParameterTable.length, 0);
1357}
1358
1359TEST(GetFirmwareParameters, decodeResponseErrorCompletionCode)
1360{
1361 constexpr std::array<uint8_t, hdrSize + sizeof(uint8_t)>
1362 getFwParamsResponse{0x00, 0x00, 0x00, 0x01};
1363
1364 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301365 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301366 reinterpret_cast<const pldm_msg*>(getFwParamsResponse.data());
1367 pldm_get_firmware_parameters_resp outResp{};
1368 variable_field outActiveCompImageSetVersion{};
1369 variable_field outPendingCompImageSetVersion{};
1370 variable_field outCompParameterTable{};
1371
1372 auto rc = decode_get_firmware_parameters_resp(
1373 responseMsg, getFwParamsResponse.size(), &outResp,
1374 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1375 &outCompParameterTable);
1376
1377 EXPECT_EQ(rc, PLDM_SUCCESS);
1378 EXPECT_EQ(outResp.completion_code, PLDM_ERROR);
1379}
1380
1381TEST(GetFirmwareParameters, errorPathdecodeResponse)
1382{
1383 int rc = 0;
1384 // Invalid ActiveComponentImageSetVersionStringType
1385 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse1{
1386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1387 0x00, 0x00, 0x00, 0x06, 0x0e, 0x00, 0x00};
1388
1389 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301390 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301391 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse1.data());
1392 pldm_get_firmware_parameters_resp outResp{};
1393 variable_field outActiveCompImageSetVersion{};
1394 variable_field outPendingCompImageSetVersion{};
1395 variable_field outCompParameterTable{};
1396
1397 rc = decode_get_firmware_parameters_resp(
1398 nullptr, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1399 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1400 &outCompParameterTable);
1401 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1402
1403 rc = decode_get_firmware_parameters_resp(
1404 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, nullptr,
1405 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1406 &outCompParameterTable);
1407 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1408
1409 rc = decode_get_firmware_parameters_resp(
1410 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1411 nullptr, &outPendingCompImageSetVersion, &outCompParameterTable);
1412 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1413
1414 rc = decode_get_firmware_parameters_resp(
1415 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1416 &outActiveCompImageSetVersion, nullptr, &outCompParameterTable);
1417 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1418
1419 rc = decode_get_firmware_parameters_resp(
1420 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1421 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion, nullptr);
1422 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1423
1424 rc = decode_get_firmware_parameters_resp(
1425 responseMsg, 0, &outResp, &outActiveCompImageSetVersion,
1426 &outPendingCompImageSetVersion, &outCompParameterTable);
1427 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1428
1429 rc = decode_get_firmware_parameters_resp(
1430 responseMsg, invalidGetFwParamsResponse1.size() - 1 - hdrSize, &outResp,
1431 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1432 &outCompParameterTable);
1433 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1434
1435 rc = decode_get_firmware_parameters_resp(
1436 responseMsg, invalidGetFwParamsResponse1.size() - hdrSize, &outResp,
1437 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1438 &outCompParameterTable);
1439 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1440
1441 // Invalid ActiveComponentImageSetVersionStringLength
1442 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse2{
1443 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1444 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00};
1445 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301446 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301447 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse2.data());
1448 rc = decode_get_firmware_parameters_resp(
1449 responseMsg, invalidGetFwParamsResponse2.size() - hdrSize, &outResp,
1450 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1451 &outCompParameterTable);
1452 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1453
1454 // Invalid PendingComponentImageSetVersionStringType &
1455 // PendingComponentImageSetVersionStringLength
1456 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse3{
1457 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1458 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x00};
1459 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301460 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301461 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse3.data());
1462 rc = decode_get_firmware_parameters_resp(
1463 responseMsg, invalidGetFwParamsResponse3.size() - hdrSize, &outResp,
1464 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1465 &outCompParameterTable);
1466 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1467
1468 // Invalid PendingComponentImageSetVersionStringType &
1469 // PendingComponentImageSetVersionStringLength
1470 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse4{
1471 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1472 0x00, 0x00, 0x00, 0x01, 0x0e, 0x06, 0x0e};
1473 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301474 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301475 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse4.data());
1476 rc = decode_get_firmware_parameters_resp(
1477 responseMsg, invalidGetFwParamsResponse4.size() - hdrSize, &outResp,
1478 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1479 &outCompParameterTable);
1480 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
1481
1482 // Total payload length less than expected
1483 constexpr std::array<uint8_t, 14> invalidGetFwParamsResponse5{
1484 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
1485 0x00, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x0e};
1486 responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301487 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301488 reinterpret_cast<const pldm_msg*>(invalidGetFwParamsResponse5.data());
1489 rc = decode_get_firmware_parameters_resp(
1490 responseMsg, invalidGetFwParamsResponse5.size() - hdrSize, &outResp,
1491 &outActiveCompImageSetVersion, &outPendingCompImageSetVersion,
1492 &outCompParameterTable);
1493 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
1494}
1495
1496TEST(GetFirmwareParameters, goodPathDecodeComponentParameterEntry)
1497{
1498 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001499 constexpr uint16_t compClassification = 0x0a0b;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301500 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001501 constexpr uint16_t compIdentifier = 0x0c0d;
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001502 constexpr uint16_t compClassificationIndex = 0xf;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301503 // Random value for component classification
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001504 constexpr uint32_t timestamp = 0x12345678;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301505 // Random value for component activation methods
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001506 constexpr uint16_t compActivationMethods = 0xbbdd;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301507 // Random value for capabilities during update
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001508 constexpr uint32_t capabilitiesDuringUpdate = 0xbadbeefe;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301509
1510 // ActiveCompImageSetVerStrLen is not fixed here taking it as 8
1511 constexpr uint8_t activeCompVerStrLen = 8;
1512 // PendingCompImageSetVerStrLen is not fixed here taking it as 8
1513 constexpr uint8_t pendingCompVerStrLen = 8;
1514 constexpr size_t entryLength =
1515 sizeof(struct pldm_component_parameter_entry) + activeCompVerStrLen +
1516 pendingCompVerStrLen;
1517 std::array<uint8_t, entryLength> entry{};
1518
1519 auto inEntry =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301520 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09301521 reinterpret_cast<struct pldm_component_parameter_entry*>(entry.data());
1522
1523 inEntry->comp_classification = htole16(compClassification);
1524 inEntry->comp_identifier = htole16(compIdentifier);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001525 inEntry->comp_classification_index = compClassificationIndex;
Andrew Jeffery9c766792022-08-10 23:12:49 +09301526 inEntry->active_comp_comparison_stamp = htole32(timestamp);
1527 inEntry->active_comp_ver_str_type = 1;
1528 inEntry->active_comp_ver_str_len = activeCompVerStrLen;
1529 std::fill_n(inEntry->active_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001530 sizeof(inEntry->active_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301531 inEntry->pending_comp_comparison_stamp = htole32(timestamp);
1532 inEntry->pending_comp_ver_str_type = 1;
1533 inEntry->pending_comp_ver_str_len = pendingCompVerStrLen;
1534 std::fill_n(inEntry->pending_comp_release_date,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001535 sizeof(inEntry->pending_comp_release_date), 0xff);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301536 inEntry->comp_activation_methods.value = htole16(compActivationMethods);
1537 inEntry->capabilities_during_update.value =
1538 htole32(capabilitiesDuringUpdate);
1539 constexpr auto activeCompVerStrPos =
1540 sizeof(struct pldm_component_parameter_entry);
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001541 std::fill_n(entry.data() + activeCompVerStrPos, activeCompVerStrLen, 0xaa);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301542 constexpr auto pendingCompVerStrPos =
1543 activeCompVerStrPos + activeCompVerStrLen;
1544 std::fill_n(entry.data() + pendingCompVerStrPos, pendingCompVerStrLen,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06001545 0xbb);
Andrew Jeffery9c766792022-08-10 23:12:49 +09301546
1547 struct pldm_component_parameter_entry outEntry;
1548 struct variable_field outActiveCompVerStr;
1549 struct variable_field outPendingCompVerStr;
1550
1551 auto rc = decode_get_firmware_parameters_resp_comp_entry(
1552 entry.data(), entryLength, &outEntry, &outActiveCompVerStr,
1553 &outPendingCompVerStr);
1554
1555 EXPECT_EQ(rc, PLDM_SUCCESS);
1556
1557 EXPECT_EQ(outEntry.comp_classification, compClassification);
1558 EXPECT_EQ(outEntry.comp_identifier, compIdentifier);
1559 EXPECT_EQ(inEntry->comp_classification_index,
1560 outEntry.comp_classification_index);
1561 EXPECT_EQ(outEntry.active_comp_comparison_stamp, timestamp);
1562 EXPECT_EQ(inEntry->active_comp_ver_str_type,
1563 outEntry.active_comp_ver_str_type);
1564 EXPECT_EQ(inEntry->active_comp_ver_str_len,
1565 outEntry.active_comp_ver_str_len);
1566 EXPECT_EQ(0, memcmp(inEntry->active_comp_release_date,
1567 outEntry.active_comp_release_date,
1568 sizeof(inEntry->active_comp_release_date)));
1569 EXPECT_EQ(outEntry.pending_comp_comparison_stamp, timestamp);
1570 EXPECT_EQ(inEntry->pending_comp_ver_str_type,
1571 outEntry.pending_comp_ver_str_type);
1572 EXPECT_EQ(inEntry->pending_comp_ver_str_len,
1573 outEntry.pending_comp_ver_str_len);
1574 EXPECT_EQ(0, memcmp(inEntry->pending_comp_release_date,
1575 outEntry.pending_comp_release_date,
1576 sizeof(inEntry->pending_comp_release_date)));
1577 EXPECT_EQ(outEntry.comp_activation_methods.value, compActivationMethods);
1578 EXPECT_EQ(outEntry.capabilities_during_update.value,
1579 capabilitiesDuringUpdate);
1580
1581 EXPECT_EQ(0, memcmp(outActiveCompVerStr.ptr,
1582 entry.data() + activeCompVerStrPos,
1583 outActiveCompVerStr.length));
1584 EXPECT_EQ(0, memcmp(outPendingCompVerStr.ptr,
1585 entry.data() + pendingCompVerStrPos,
1586 outPendingCompVerStr.length));
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08001587
1588#ifdef LIBPLDM_API_TESTING
1589 /* Check the roundtrip matches */
1590 std::vector<uint8_t> enc_data(1000);
1591 size_t enc_payload_len = enc_data.size();
1592 struct pldm_component_parameter_entry_full entryFull = {
1593 .comp_classification = compClassification,
1594 .comp_identifier = compIdentifier,
1595 .comp_classification_index = compClassificationIndex,
1596 .active_ver =
1597 {
1598 .comparison_stamp = 0x12345678,
1599 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1600 .str_len = activeCompVerStrLen,
1601 .str_data = {}},
1602 .date = {},
1603 },
1604 .pending_ver =
1605 {
1606 .comparison_stamp = 0x12345678,
1607 .str = {.str_type = PLDM_STR_TYPE_ASCII,
1608 .str_len = pendingCompVerStrLen,
1609 .str_data = {}},
1610 .date = {},
1611 },
1612 .comp_activation_methods = inEntry->comp_activation_methods,
1613 .capabilities_during_update = inEntry->capabilities_during_update,
1614 };
1615 // Fill strings
1616 std::fill_n(entryFull.active_ver.str.str_data, activeCompVerStrLen, 0xaa);
1617 std::fill_n(entryFull.pending_ver.str.str_data, pendingCompVerStrLen, 0xbb);
1618 std::fill_n(entryFull.active_ver.date, PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN,
1619 0xff);
1620 std::fill_n(entryFull.pending_ver.date,
1621 PLDM_FWUP_COMPONENT_RELEASE_DATA_LEN, 0xff);
1622
1623 rc = encode_get_firmware_parameters_resp_comp_entry(
1624 &entryFull, enc_data.data(), &enc_payload_len);
1625 EXPECT_EQ(rc, PLDM_SUCCESS);
1626 EXPECT_EQ(enc_payload_len, entryLength);
1627 EXPECT_TRUE(std::equal(entry.begin(), entry.end(), enc_data.begin()));
1628#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09301629}
1630
Chris Wang4c1f2c72024-03-21 17:09:44 +08001631TEST(QueryDownstreamDevices, goodPathEncodeRequest)
1632{
1633 constexpr uint8_t instanceId = 1;
1634 std::array<uint8_t, sizeof(pldm_msg_hdr)> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301635 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001636 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1637
1638 auto rc = encode_query_downstream_devices_req(instanceId, requestPtr);
1639
Unive Tien71e935c2024-11-25 17:21:43 +08001640 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001641 EXPECT_EQ(requestPtr->hdr.request, PLDM_REQUEST);
1642 EXPECT_EQ(requestPtr->hdr.instance_id, instanceId);
1643 EXPECT_EQ(requestPtr->hdr.type, PLDM_FWUP);
1644 EXPECT_EQ(requestPtr->hdr.command, PLDM_QUERY_DOWNSTREAM_DEVICES);
1645}
1646
1647TEST(QueryDownstreamDevices, encodeRequestInvalidData)
1648{
1649 constexpr uint8_t instanceId = 1;
1650
1651 auto rc = encode_query_downstream_devices_req(instanceId, nullptr);
1652
Unive Tien71e935c2024-11-25 17:21:43 +08001653 EXPECT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001654}
1655
1656TEST(QueryDownstreamDevices, goodPathDecodeResponse)
1657{
1658 uint8_t completion_code_resp = PLDM_SUCCESS;
1659 uint8_t downstream_device_update_supported_resp =
1660 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1661 uint16_t number_of_downstream_devices_resp = 1;
1662 uint16_t max_number_of_downstream_devices_resp = 1;
1663 /** Capabilities of updating downstream devices
1664 * FDP supports downstream devices dynamically attached [Bit position 0] &
1665 * FDP supports downstream devices dynamically removed [Bit position 1]
1666 */
1667 bitfield32_t capabilities_resp = {.value = 0x0002};
1668 int rc;
1669
1670 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1671 responseMsg{};
1672
Andrew Jefferya1896962025-03-03 21:41:25 +10301673 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301674 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1675 responseMsg.size() - hdrSize);
1676 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001677
1678 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1679 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1680 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1681 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1682 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301683 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001684
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301685 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001686 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1687 struct pldm_query_downstream_devices_resp resp_data;
1688
1689 rc = decode_query_downstream_devices_resp(
1690 response, responseMsg.size() - hdrSize, &resp_data);
1691
Unive Tien71e935c2024-11-25 17:21:43 +08001692 EXPECT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001693 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1694 EXPECT_EQ(resp_data.downstream_device_update_supported,
1695 downstream_device_update_supported_resp);
1696 EXPECT_EQ(resp_data.number_of_downstream_devices,
1697 number_of_downstream_devices_resp);
1698 EXPECT_EQ(resp_data.max_number_of_downstream_devices,
1699 max_number_of_downstream_devices_resp);
1700 EXPECT_EQ(resp_data.capabilities.value, capabilities_resp.value);
1701}
1702
1703TEST(QueryDownstreamDevices, decodeRequestUndefinedValue)
1704{
1705 uint8_t completion_code_resp = PLDM_SUCCESS;
1706 uint8_t downstream_device_update_supported_resp = 0xe; /*Undefined value*/
1707 uint16_t number_of_downstream_devices_resp = 1;
1708 uint16_t max_number_of_downstream_devices_resp = 1;
1709 /** Capabilities of updating downstream devices
1710 * FDP supports downstream devices dynamically attached [Bit position 0] &
1711 * FDP supports downstream devices dynamically removed [Bit position 1]
1712 */
1713 bitfield32_t capabilities_resp = {.value = 0x0002};
1714 int rc;
1715
1716 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES>
1717 responseMsg{};
1718
Andrew Jefferya1896962025-03-03 21:41:25 +10301719 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301720 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1721 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301722 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001723 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1724 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1725 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1726 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1727 pldm_msgbuf_insert_uint32(buf, capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301728 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001729
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301730 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001731 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1732 struct pldm_query_downstream_devices_resp resp_data;
1733
1734 rc = decode_query_downstream_devices_resp(
1735 response, responseMsg.size() - hdrSize, &resp_data);
1736
Unive Tien71e935c2024-11-25 17:21:43 +08001737 ASSERT_EQ(rc, -EINVAL);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001738}
1739
1740TEST(QueryDownstreamDevices, decodeRequestErrorBufSize)
1741{
1742 uint8_t completion_code_resp = PLDM_SUCCESS;
1743 uint8_t downstream_device_update_supported_resp =
1744 PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED;
1745 uint16_t number_of_downstream_devices_resp = 1;
1746 uint16_t max_number_of_downstream_devices_resp = 1;
1747 /** Capabilities of updating downstream devices
1748 * FDP supports downstream devices dynamically attached [Bit position 0] &
1749 * FDP supports downstream devices dynamically removed [Bit position 1]
1750 */
1751 bitfield32_t capabilities_resp = {.value = 0x0002};
1752 int rc;
1753
1754 std::array<uint8_t, hdrSize + PLDM_QUERY_DOWNSTREAM_DEVICES_RESP_BYTES -
1755 2 /* Inject error length*/>
1756 responseMsg{};
1757
Andrew Jefferya1896962025-03-03 21:41:25 +10301758 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery830c1eb2024-10-04 10:48:10 +09301759 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
1760 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10301761 ASSERT_EQ(rc, 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001762
1763 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1764 pldm_msgbuf_insert_uint8(buf, downstream_device_update_supported_resp);
1765 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1766 pldm_msgbuf_insert_uint16(buf, max_number_of_downstream_devices_resp);
1767 // Inject error value
1768 pldm_msgbuf_insert_uint16(buf, (uint16_t)capabilities_resp.value);
Andrew Jefferya1896962025-03-03 21:41:25 +10301769 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001770
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301771 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang4c1f2c72024-03-21 17:09:44 +08001772 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
1773 struct pldm_query_downstream_devices_resp resp_data;
1774
1775 rc = decode_query_downstream_devices_resp(
1776 response, responseMsg.size() - hdrSize, &resp_data);
1777
Unive Tien71e935c2024-11-25 17:21:43 +08001778 EXPECT_EQ(rc, -EBADMSG);
Chris Wang4c1f2c72024-03-21 17:09:44 +08001779}
1780
Chris Wang458475a2024-03-26 17:59:19 +08001781TEST(QueryDownstreamIdentifiers, goodPathEncodeRequest)
1782{
1783 constexpr uint8_t instanceId = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301784 constexpr size_t payloadLen = PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1785 PLDM_MSG_DEFINE_P(request, payloadLen);
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001786 constexpr pldm_query_downstream_identifiers_req params_req{
1787 0xFFFFFFFF, PLDM_GET_FIRSTPART};
Chris Wang458475a2024-03-26 17:59:19 +08001788
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001789 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1790 request, payloadLen);
Unive Tien71e935c2024-11-25 17:21:43 +08001791 ASSERT_EQ(rc, 0);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301792 EXPECT_THAT(std::span<uint8_t>(request_buf, sizeof(request_buf)),
1793 ElementsAreArray<uint8_t>(
1794 {0x81, 0x05, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0x01}));
Chris Wang458475a2024-03-26 17:59:19 +08001795}
1796
1797TEST(QueryDownstreamIdentifiers, encodeRequestInvalidErrorPaths)
1798{
1799 constexpr uint8_t instanceId = 1;
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001800 constexpr pldm_query_downstream_identifiers_req params_req{
1801 0xFFFFFFFF, PLDM_GET_FIRSTPART};
1802 constexpr pldm_query_downstream_identifiers_req params_req_invalid{
1803 0xFFFFFFFF, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wang458475a2024-03-26 17:59:19 +08001804 constexpr size_t payload_length =
1805 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES;
1806 std::array<uint8_t, hdrSize + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09301807 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wang458475a2024-03-26 17:59:19 +08001808 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
1809
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001810 auto rc = encode_query_downstream_identifiers_req(instanceId, &params_req,
1811 nullptr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001812 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001813
1814 rc = encode_query_downstream_identifiers_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001815 instanceId, &params_req, requestPtr, payload_length - 1);
Unive Tien71e935c2024-11-25 17:21:43 +08001816 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wang458475a2024-03-26 17:59:19 +08001817
Unive Tiend2f8a7e2024-11-27 10:59:34 +08001818 rc = encode_query_downstream_identifiers_req(
1819 instanceId, &params_req_invalid, requestPtr, payload_length);
Unive Tien71e935c2024-11-25 17:21:43 +08001820 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08001821}
1822
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301823TEST(QueryDownstreamIdentifiers, decodeResponseNoDevices)
Chris Wang458475a2024-03-26 17:59:19 +08001824{
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301825 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1826 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1827 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1828 constexpr uint32_t downstream_devices_length_resp = 0;
1829 constexpr uint16_t number_of_downstream_devices_resp = 0;
1830
1831 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1832 struct pldm_query_downstream_identifiers_resp resp_data = {};
1833 struct pldm_downstream_device_iter devs;
Andrew Jefferya1896962025-03-03 21:41:25 +10301834 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301835 int rc = 0;
1836
1837 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1838 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1839 ASSERT_EQ(rc, 0);
1840
1841 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1842 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1843 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1844 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1845 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1846
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301847 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301848
1849 rc = decode_query_downstream_identifiers_resp(
1850 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp_data,
1851 &devs);
1852
Unive Tien71e935c2024-11-25 17:21:43 +08001853 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301854 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
1855 EXPECT_EQ(resp_data.next_data_transfer_handle,
1856 next_data_transfer_handle_resp);
1857 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1858 EXPECT_EQ(resp_data.downstream_devices_length,
1859 downstream_devices_length_resp);
1860 EXPECT_EQ(resp_data.number_of_downstream_devices,
1861 number_of_downstream_devices_resp);
1862}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301863
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301864TEST(QueryDownstreamIdentifiers, decodeResponseNoDevicesBadCount)
1865{
1866 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1867 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1868 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1869 constexpr uint32_t downstream_devices_length_resp = 0;
1870 constexpr uint16_t number_of_downstream_devices_resp = 1;
1871
1872 PLDM_MSG_DEFINE_P(response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1873 struct pldm_query_downstream_identifiers_resp resp = {};
1874 struct pldm_downstream_device_iter devs;
1875 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301876 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301877 int rc = 0;
1878
1879 rc = pldm_msgbuf_init_errno(buf, 0, response->payload,
1880 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN);
1881 ASSERT_EQ(rc, 0);
1882
1883 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
1884 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1885 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1886 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1887 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1888
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301889 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301890
1891 rc = decode_query_downstream_identifiers_resp(
1892 response, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN, &resp, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08001893 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301894
1895 foreach_pldm_downstream_device(devs, dev, rc)
1896 {
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10301897 FAIL();
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301898 }
1899 ASSERT_NE(rc, 0);
1900}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301901
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301902TEST(QueryDownstreamIdentifiers, decodeResponseOneDeviceOneDescriptor)
1903{
1904 constexpr uint32_t downstreamDevicesLen = 11;
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301905 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wang458475a2024-03-26 17:59:19 +08001906 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1907 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1908 const uint32_t downstream_devices_length_resp =
1909 htole32(downstreamDevicesLen);
1910 constexpr uint16_t number_of_downstream_devices_resp = 1;
Andrew Jefferydec237b2024-11-08 14:33:45 +10301911 constexpr size_t payloadLen =
1912 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstreamDevicesLen;
Chris Wang458475a2024-03-26 17:59:19 +08001913
Andrew Jefferydec237b2024-11-08 14:33:45 +10301914 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jefferydec237b2024-11-08 14:33:45 +10301915 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301916 struct pldm_downstream_device_iter devs;
1917 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10301918 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10301919 int rc = 0;
1920
1921 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
1922 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08001923
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301924 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001925 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
1926 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
1927 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
1928 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
1929
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301930 /* Downstream device */
1931 pldm_msgbuf_insert_uint16(buf, 1);
1932 pldm_msgbuf_insert_uint8(buf, 1);
Chris Wang458475a2024-03-26 17:59:19 +08001933
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301934 /* Device descriptor */
1935 pldm_msgbuf_insert_uint16(buf, 1);
1936 pldm_msgbuf_insert_uint16(buf, 4);
1937 pldm_msgbuf_insert_uint32(buf, 412);
Chris Wang458475a2024-03-26 17:59:19 +08001938
Andrew Jeffery70d21c92025-03-05 12:59:42 +10301939 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301940
1941 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
1942 &resp_data, &devs);
1943
Unive Tien71e935c2024-11-25 17:21:43 +08001944 ASSERT_EQ(rc, 0);
Andrew Jefferycd2eb602024-11-08 11:41:58 +10301945 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wang458475a2024-03-26 17:59:19 +08001946 EXPECT_EQ(resp_data.next_data_transfer_handle,
1947 next_data_transfer_handle_resp);
1948 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
1949 EXPECT_EQ(resp_data.downstream_devices_length,
1950 downstream_devices_length_resp);
1951 EXPECT_EQ(resp_data.number_of_downstream_devices,
1952 number_of_downstream_devices_resp);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301953
1954 foreach_pldm_downstream_device(devs, dev, rc)
1955 {
1956 struct pldm_descriptor desc;
1957
1958 EXPECT_EQ(dev.downstream_device_index, 1);
1959 EXPECT_EQ(dev.downstream_descriptor_count, 1);
1960
1961 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
1962 {
1963 static const uint32_t dmtf = htole32(412);
1964 EXPECT_EQ(desc.descriptor_type, 1);
1965 EXPECT_EQ(desc.descriptor_length, 4);
1966 EXPECT_EQ(memcmp(desc.descriptor_data, &dmtf, sizeof(dmtf)), 0);
1967 }
1968 ASSERT_EQ(rc, 0);
1969 }
1970 ASSERT_EQ(rc, 0);
1971}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301972
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301973constexpr const uint16_t descriptor_id_type_iana_pen = 0x1;
1974constexpr const uint16_t descriptor_id_len_iana_pen = 0x4;
1975const uint32_t iana_pen_openbmc = htole16(49871u);
1976const uint32_t iana_pen_dmtf = htole16(412u);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301977
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10301978TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneDescriptorEach)
1979{
1980 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
1981 {0, 1},
1982 {1, 1},
1983 }};
1984
1985 constexpr const std::array<pldm_descriptor, 2> expected_descriptors = {{
1986 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1987 &iana_pen_dmtf},
1988 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
1989 &iana_pen_openbmc},
1990 }};
1991
1992 constexpr uint32_t downstream_devices_len = 22;
1993 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
1994 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
1995 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
1996 const uint32_t downstream_devices_length_resp =
1997 htole32(downstream_devices_len);
1998 constexpr uint16_t number_of_downstream_devices_resp = 2;
1999 constexpr size_t payloadLen =
2000 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2001
Patrick Williamsf37edd72024-12-18 11:22:58 -05002002 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302003 PLDM_MSG_DEFINE_P(response, payloadLen);
2004 struct pldm_downstream_device_iter devs;
2005 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302006 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302007 int rc = 0;
2008
2009 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2010 ASSERT_EQ(rc, 0);
2011
2012 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2013 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2014 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2015 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2016 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2017
2018 /* Downstream device */
2019 pldm_msgbuf_insert_uint16(buf, 0);
2020 pldm_msgbuf_insert_uint8(buf, 1);
2021
2022 /* Device descriptor */
2023 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2024 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2025 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2026
2027 /* Downstream device */
2028 pldm_msgbuf_insert_uint16(buf, 1);
2029 pldm_msgbuf_insert_uint8(buf, 1);
2030
2031 /* Device descriptor */
2032 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2033 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2034 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2035
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302036 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302037
2038 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2039 &resp_data, &devs);
2040
Unive Tien71e935c2024-11-25 17:21:43 +08002041 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302042 EXPECT_EQ(resp_data.number_of_downstream_devices,
2043 number_of_downstream_devices_resp);
2044
2045 size_t devIndex = 0;
2046 size_t descIndex = 0;
2047 foreach_pldm_downstream_device(devs, dev, rc)
2048 {
2049 struct pldm_descriptor desc;
2050
2051 ASSERT_LT(devIndex, expected_devices.size());
2052
2053 const struct pldm_downstream_device* expectedDev =
2054 &expected_devices[devIndex];
2055
2056 EXPECT_EQ(dev.downstream_device_index,
2057 expectedDev->downstream_device_index);
2058 EXPECT_EQ(dev.downstream_descriptor_count,
2059 expectedDev->downstream_descriptor_count);
2060
2061 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2062 {
2063 ASSERT_LT(descIndex, expected_descriptors.size());
2064
2065 const struct pldm_descriptor* expectedDesc =
2066 &expected_descriptors[descIndex];
2067
2068 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2069 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2070 EXPECT_EQ(memcmp(desc.descriptor_data,
2071 expectedDesc->descriptor_data,
2072 expectedDesc->descriptor_length),
2073 0);
2074
2075 descIndex++;
2076 }
2077 ASSERT_EQ(rc, 0);
2078 EXPECT_EQ(descIndex, 1 * devIndex + 1);
2079
2080 devIndex++;
2081 }
2082 ASSERT_EQ(rc, 0);
2083 EXPECT_EQ(devIndex, 2);
2084}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302085
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302086TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesTwoOneDescriptors)
2087{
2088 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2089 {0, 2},
2090 {1, 1},
2091 }};
2092
2093 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2094 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2095 &iana_pen_dmtf},
2096 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2097 &iana_pen_openbmc},
2098 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2099 &iana_pen_dmtf},
2100 }};
2101
2102 constexpr uint32_t downstream_devices_len = 30;
2103 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2104 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2105 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2106 const uint32_t downstream_devices_length_resp =
2107 htole32(downstream_devices_len);
2108 constexpr uint16_t number_of_downstream_devices_resp = 2;
2109 constexpr size_t payloadLen =
2110 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2111
Patrick Williamsf37edd72024-12-18 11:22:58 -05002112 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302113 PLDM_MSG_DEFINE_P(response, payloadLen);
2114 struct pldm_downstream_device_iter devs;
2115 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302116 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302117 int rc = 0;
2118
2119 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2120 ASSERT_EQ(rc, 0);
2121
2122 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2123 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2124 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2125 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2126 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2127
2128 /* Downstream device */
2129 pldm_msgbuf_insert_uint16(buf, 0);
2130 pldm_msgbuf_insert_uint8(buf, 2);
2131
2132 /* Device descriptor */
2133 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2134 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2135 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2136
2137 /* Device descriptor */
2138 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2139 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2140 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2141
2142 /* Downstream device */
2143 pldm_msgbuf_insert_uint16(buf, 1);
2144 pldm_msgbuf_insert_uint8(buf, 1);
2145
2146 /* Device descriptor */
2147 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2148 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2149 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2150
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302151 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302152
2153 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2154 &resp_data, &devs);
2155
Unive Tien71e935c2024-11-25 17:21:43 +08002156 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302157 EXPECT_EQ(resp_data.number_of_downstream_devices,
2158 number_of_downstream_devices_resp);
2159
2160 size_t devIndex = 0;
2161 size_t descIndex = 0;
2162 foreach_pldm_downstream_device(devs, dev, rc)
2163 {
2164 struct pldm_descriptor desc;
2165
2166 ASSERT_LT(devIndex, expected_devices.size());
2167
2168 const struct pldm_downstream_device* expectedDev =
2169 &expected_devices[devIndex];
2170
2171 EXPECT_EQ(dev.downstream_device_index,
2172 expectedDev->downstream_device_index);
2173 EXPECT_EQ(dev.downstream_descriptor_count,
2174 expectedDev->downstream_descriptor_count);
2175
2176 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2177 {
2178 ASSERT_LT(descIndex, expected_descriptors.size());
2179
2180 const struct pldm_descriptor* expectedDesc =
2181 &expected_descriptors[descIndex];
2182
2183 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2184 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2185 EXPECT_EQ(memcmp(desc.descriptor_data,
2186 expectedDesc->descriptor_data,
2187 expectedDesc->descriptor_length),
2188 0);
2189
2190 descIndex++;
2191 }
2192 ASSERT_EQ(rc, 0);
2193
2194 devIndex++;
2195 }
2196 ASSERT_EQ(rc, 0);
2197 EXPECT_EQ(devIndex, 2);
2198 EXPECT_EQ(descIndex, 3);
2199}
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302200
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302201TEST(QueryDownstreamIdentifiers, decodeResponseTwoDevicesOneTwoDescriptors)
2202{
2203 constexpr const std::array<pldm_downstream_device, 2> expected_devices = {{
2204 {0, 1},
2205 {1, 2},
2206 }};
2207
2208 constexpr const std::array<pldm_descriptor, 3> expected_descriptors = {{
2209 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2210 &iana_pen_dmtf},
2211 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2212 &iana_pen_openbmc},
2213 {descriptor_id_type_iana_pen, descriptor_id_len_iana_pen,
2214 &iana_pen_dmtf},
2215 }};
2216
2217 constexpr uint32_t downstream_devices_len = 30;
2218 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2219 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2220 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2221 const uint32_t downstream_devices_length_resp =
2222 htole32(downstream_devices_len);
2223 constexpr uint16_t number_of_downstream_devices_resp = 2;
2224 constexpr size_t payloadLen =
2225 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN + downstream_devices_len;
2226
Patrick Williamsf37edd72024-12-18 11:22:58 -05002227 struct pldm_query_downstream_identifiers_resp resp_data{};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302228 PLDM_MSG_DEFINE_P(response, payloadLen);
2229 struct pldm_downstream_device_iter devs;
2230 struct pldm_downstream_device dev;
Andrew Jefferya1896962025-03-03 21:41:25 +10302231 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302232 int rc = 0;
2233
2234 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2235 ASSERT_EQ(rc, 0);
2236
2237 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2238 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2239 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2240 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2241 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
2242
2243 /* Downstream device */
2244 pldm_msgbuf_insert_uint16(buf, 0);
2245 pldm_msgbuf_insert_uint8(buf, 1);
2246
2247 /* Device descriptor */
2248 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2249 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2250 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2251
2252 /* Downstream device */
2253 pldm_msgbuf_insert_uint16(buf, 1);
2254 pldm_msgbuf_insert_uint8(buf, 2);
2255
2256 /* Device descriptor */
2257 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2258 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2259 pldm_msgbuf_insert_uint32(buf, iana_pen_openbmc);
2260
2261 /* Device descriptor */
2262 pldm_msgbuf_insert_uint16(buf, descriptor_id_type_iana_pen);
2263 pldm_msgbuf_insert_uint16(buf, descriptor_id_len_iana_pen);
2264 pldm_msgbuf_insert_uint32(buf, iana_pen_dmtf);
2265
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302266 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302267
2268 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2269 &resp_data, &devs);
2270
Unive Tien71e935c2024-11-25 17:21:43 +08002271 ASSERT_EQ(rc, 0);
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302272 EXPECT_EQ(resp_data.number_of_downstream_devices,
2273 number_of_downstream_devices_resp);
2274
2275 size_t devIndex = 0;
2276 size_t descIndex = 0;
2277 foreach_pldm_downstream_device(devs, dev, rc)
2278 {
2279 struct pldm_descriptor desc;
2280
2281 ASSERT_LT(devIndex, expected_devices.size());
2282
2283 const struct pldm_downstream_device* expectedDev =
2284 &expected_devices[devIndex];
2285
2286 EXPECT_EQ(dev.downstream_device_index,
2287 expectedDev->downstream_device_index);
2288 EXPECT_EQ(dev.downstream_descriptor_count,
2289 expectedDev->downstream_descriptor_count);
2290
2291 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
2292 {
2293 ASSERT_LT(descIndex, expected_descriptors.size());
2294
2295 const struct pldm_descriptor* expectedDesc =
2296 &expected_descriptors[descIndex];
2297
2298 EXPECT_EQ(desc.descriptor_type, expectedDesc->descriptor_type);
2299 ASSERT_EQ(desc.descriptor_length, expectedDesc->descriptor_length);
2300 EXPECT_EQ(memcmp(desc.descriptor_data,
2301 expectedDesc->descriptor_data,
2302 expectedDesc->descriptor_length),
2303 0);
2304
2305 descIndex++;
2306 }
2307 ASSERT_EQ(rc, 0);
2308
2309 devIndex++;
2310 }
2311 ASSERT_EQ(rc, 0);
2312 EXPECT_EQ(devIndex, 2);
2313 EXPECT_EQ(descIndex, 3);
Chris Wang458475a2024-03-26 17:59:19 +08002314}
2315
2316TEST(QueryDownstreamIdentifiers, decodeRequestErrorPaths)
2317{
Andrew Jefferydec237b2024-11-08 14:33:45 +10302318 constexpr size_t payloadLen = sizeof(uint8_t);
2319
Chris Wang458475a2024-03-26 17:59:19 +08002320 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302321 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302322 PLDM_MSG_DEFINE_P(response, payloadLen);
Chris Wang458475a2024-03-26 17:59:19 +08002323
2324 // Test nullptr
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302325 auto rc = decode_query_downstream_identifiers_resp(nullptr, payloadLen,
2326 nullptr, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002327 EXPECT_EQ(rc, -EINVAL);
Chris Wang458475a2024-03-26 17:59:19 +08002328
2329 // Test not PLDM_SUCCESS completion code
2330 response->payload[0] = PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302331 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2332 &resp_data, &devs);
Unive Tien71e935c2024-11-25 17:21:43 +08002333 EXPECT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002334 EXPECT_EQ(resp_data.completion_code, PLDM_ERROR_UNSUPPORTED_PLDM_CMD);
2335
2336 // Test payload length less than minimum length
2337 response->payload[0] = PLDM_SUCCESS;
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302338 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2339 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002340
Unive Tien71e935c2024-11-25 17:21:43 +08002341 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002342}
2343
2344TEST(QueryDownstreamIdentifiers, decodeRequestErrorDownstreamDevicesSize)
2345{
Manojkiran Eda9e3a5d42024-06-17 16:06:42 +05302346 // Len is not fixed here taking it as 9, contains 1 downstream device with
Chris Wang458475a2024-03-26 17:59:19 +08002347 // 1 descriptor
2348 constexpr uint32_t actualDownstreamDevicesLen = 9;
2349 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2350 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2351 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302352 constexpr uint16_t number_of_downstream_devices_resp = 1;
2353 constexpr size_t payloadLen =
2354 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN +
2355 actualDownstreamDevicesLen;
2356
Chris Wang458475a2024-03-26 17:59:19 +08002357 const uint32_t downstream_devices_length_resp =
2358 htole32(actualDownstreamDevicesLen + 1 /* inject error length*/);
Chris Wang458475a2024-03-26 17:59:19 +08002359
Andrew Jefferydec237b2024-11-08 14:33:45 +10302360 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302361 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302362 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302363 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302364 void* devicesStart = NULL;
2365 size_t devicesLen;
2366 int rc = 0;
2367
2368 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302369 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002370
2371 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2372 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2373 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2374 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2375 pldm_msgbuf_insert_uint16(buf, number_of_downstream_devices_resp);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302376 pldm_msgbuf_span_remaining(buf, &devicesStart, &devicesLen);
Chris Wang458475a2024-03-26 17:59:19 +08002377
Andrew Jefferya1896962025-03-03 21:41:25 +10302378 ASSERT_EQ(0, pldm_msgbuf_complete(buf));
2379
Chris Wang458475a2024-03-26 17:59:19 +08002380 /** Filling descriptor data, the correctness of the downstream devices data
2381 * is not checked in this test case so filling with 0xff
2382 */
Andrew Jefferydec237b2024-11-08 14:33:45 +10302383 std::fill_n(static_cast<uint8_t*>(devicesStart), actualDownstreamDevicesLen,
2384 0xff);
Chris Wang458475a2024-03-26 17:59:19 +08002385
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302386 EXPECT_NE(decode_query_downstream_identifiers_resp(response, payloadLen,
2387 &resp_data, &devs),
Unive Tien71e935c2024-11-25 17:21:43 +08002388 0);
Chris Wang458475a2024-03-26 17:59:19 +08002389}
2390
2391TEST(QueryDownstreamIdentifiers, decodeRequestErrorBufSize)
2392{
2393 constexpr uint32_t actualDownstreamDevicesLen = 0;
2394 constexpr uint16_t number_of_downstream_devices_resp = 1;
2395 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2396 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2397 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302398 constexpr size_t payloadLen =
2399 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_RESP_MIN_LEN - 1;
2400
Chris Wang458475a2024-03-26 17:59:19 +08002401 const uint32_t downstream_devices_length_resp =
2402 htole32(actualDownstreamDevicesLen);
2403
Andrew Jefferydec237b2024-11-08 14:33:45 +10302404 struct pldm_query_downstream_identifiers_resp resp_data = {};
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302405 struct pldm_downstream_device_iter devs;
Andrew Jefferydec237b2024-11-08 14:33:45 +10302406 PLDM_MSG_DEFINE_P(response, payloadLen);
Andrew Jefferya1896962025-03-03 21:41:25 +10302407 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jefferydec237b2024-11-08 14:33:45 +10302408 int rc = 0;
2409
2410 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payloadLen);
2411 ASSERT_EQ(rc, 0);
Chris Wang458475a2024-03-26 17:59:19 +08002412
2413 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2414 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2415 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2416 pldm_msgbuf_insert_uint32(buf, downstream_devices_length_resp);
2417 // Inject error buffer size
2418 pldm_msgbuf_insert_uint8(buf, (uint8_t)number_of_downstream_devices_resp);
Andrew Jefferya1896962025-03-03 21:41:25 +10302419 ASSERT_EQ(pldm_msgbuf_complete_consumed(buf), 0);
Chris Wang458475a2024-03-26 17:59:19 +08002420
Andrew Jeffery3a2c6582024-11-07 16:30:36 +10302421 rc = decode_query_downstream_identifiers_resp(response, payloadLen,
2422 &resp_data, &devs);
Chris Wang458475a2024-03-26 17:59:19 +08002423
Unive Tien71e935c2024-11-25 17:21:43 +08002424 EXPECT_EQ(rc, -EBADMSG);
Chris Wang458475a2024-03-26 17:59:19 +08002425}
2426
Chris Wangb6ef35b2024-07-03 09:35:42 +08002427TEST(GetDownstreamFirmwareParameters, goodPathEncodeRequest)
2428{
2429 constexpr uint8_t instanceId = 1;
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302430 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002431 0x0, PLDM_GET_FIRSTPART};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002432 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302433 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002434 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302435 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002436 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2437
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302438 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002439 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002440 EXPECT_EQ(rc, 0);
2441
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302442 std::array<uint8_t,
2443 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES>
Chris Wangb6ef35b2024-07-03 09:35:42 +08002444 expectedReq{0x81, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01};
2445 EXPECT_EQ(requestMsg, expectedReq);
2446}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002447
Chris Wangb6ef35b2024-07-03 09:35:42 +08002448TEST(GetDownstreamFirmwareParameters, encodeRequestInvalidTransferOperationFlag)
2449{
2450 constexpr uint8_t instanceId = 1;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002451 // Setup invalid transfer operation flag
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302452 constexpr pldm_get_downstream_firmware_parameters_req params_req{
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002453 0x0, PLDM_ACKNOWLEDGEMENT_ONLY};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002454 constexpr size_t payload_length =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302455 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002456 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302457 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002458 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2459
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302460 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002461 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002462 EXPECT_EQ(rc, -EBADMSG);
2463}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002464
Chris Wangb6ef35b2024-07-03 09:35:42 +08002465TEST(GetDownstreamFirmwareParameters, encodeRequestErrorBufSize)
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{
Andrew Jeffery53b08672025-03-04 12:26:18 +10302470 0x0, PLDM_GET_FIRSTPART};
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 1 /* inject erro length*/;
2474
2475 std::array<uint8_t, sizeof(pldm_msg_hdr) + payload_length> requestMsg{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302476 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002477 auto requestPtr = reinterpret_cast<pldm_msg*>(requestMsg.data());
2478
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302479 auto rc = encode_get_downstream_firmware_parameters_req(
Unive Tiend2f8a7e2024-11-27 10:59:34 +08002480 instanceId, &params_req, requestPtr, payload_length);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002481 EXPECT_EQ(rc, -EOVERFLOW);
2482}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002483
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302484TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseOneEntry)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002485{
Chris Wangb6ef35b2024-07-03 09:35:42 +08002486 constexpr uint16_t downstreamDeviceCount = 1;
2487 constexpr uint8_t activeComponentVersionStringLength = 8;
2488 constexpr uint8_t pendingComponentVersionStringLength = 8;
2489 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302490 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002491 activeComponentVersionStringLength +
2492 pendingComponentVersionStringLength;
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302493 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002494 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2495 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2496 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302497 constexpr size_t payload_len =
2498 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2499 downstreamDeviceParamTableLen;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002500
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302501 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302502 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302503 int rc = 0;
2504
2505 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302506 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002507
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302508 // Table 24
2509 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002510 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2511 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302512
2513 // Table 25
Chris Wangb6ef35b2024-07-03 09:35:42 +08002514 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2515 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2516
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302517 // Table 26
2518 pldm_msgbuf_insert_uint16(buf, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002519
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302520 // - Active metadata
2521 pldm_msgbuf_insert_uint32(buf, 0);
2522 pldm_msgbuf_insert_uint8(buf, 1);
2523 pldm_msgbuf_insert_uint8(buf, activeComponentVersionStringLength);
2524 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2525 ASSERT_EQ(rc, 0);
2526
2527 // - Pending metadata
2528 pldm_msgbuf_insert_uint32(buf, 0);
2529 pldm_msgbuf_insert_uint8(buf, 1);
2530 pldm_msgbuf_insert_uint8(buf, pendingComponentVersionStringLength);
2531 rc = pldm__msgbuf_insert_array_void(buf, 8, "20241206", 8);
2532 ASSERT_EQ(rc, 0);
2533
2534 // - Methods and capabilities
2535 pldm_msgbuf_insert_uint16(buf, 1);
2536 pldm_msgbuf_insert_uint32(buf, 0);
2537
2538 // - Version strings
2539 rc = pldm__msgbuf_insert_array_void(buf, activeComponentVersionStringLength,
2540 "abcdefgh", 8);
2541 ASSERT_EQ(rc, 0);
2542 rc = pldm__msgbuf_insert_array_void(
2543 buf, pendingComponentVersionStringLength, "zyxwvuts", 8);
2544 ASSERT_EQ(rc, 0);
2545
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302546 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302547 ASSERT_EQ(rc, 0);
2548
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302549 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302550 struct pldm_downstream_device_parameters_iter iter = {};
Chris Wangb6ef35b2024-07-03 09:35:42 +08002551
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302552 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2553 &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002554
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302555 ASSERT_EQ(rc, 0);
2556 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002557 EXPECT_EQ(resp_data.next_data_transfer_handle,
2558 next_data_transfer_handle_resp);
2559 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2560 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302561
2562 struct pldm_downstream_device_parameters_entry entry;
2563 size_t entries = 0;
2564 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2565 {
2566 EXPECT_EQ(entry.downstream_device_index, 0);
2567 EXPECT_EQ(entry.active_comp_comparison_stamp, 0);
2568 EXPECT_EQ(entry.active_comp_ver_str_type, 1);
2569 EXPECT_EQ(entry.active_comp_ver_str_len,
2570 activeComponentVersionStringLength);
2571 EXPECT_STREQ("20241206", entry.active_comp_release_date);
2572 EXPECT_EQ(entry.pending_comp_comparison_stamp, 0);
2573 EXPECT_EQ(entry.pending_comp_ver_str_type, 1);
2574 EXPECT_EQ(entry.pending_comp_ver_str_len,
2575 pendingComponentVersionStringLength);
2576 EXPECT_STREQ("20241206", entry.pending_comp_release_date);
2577 EXPECT_EQ(entry.comp_activation_methods.value, 1);
2578 EXPECT_EQ(entry.capabilities_during_update.value, 0);
2579 EXPECT_FALSE(memcmp("abcdefgh", entry.active_comp_ver_str,
2580 entry.active_comp_ver_str_len));
2581 EXPECT_FALSE(memcmp("zyxwvuts", entry.pending_comp_ver_str,
2582 entry.pending_comp_ver_str_len));
2583 entries++;
2584 }
2585 EXPECT_EQ(rc, 0);
2586 EXPECT_EQ(entries, 1);
2587}
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302588
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302589TEST(GetDownstreamFirmwareParameters, goodPathDecodeResponseTwoEntries)
2590{
2591 /** Count is not fixed here taking it as 1, and the downstream device's
2592 * version strings length are set to 8
2593 */
2594 constexpr uint16_t downstreamDeviceCount = 2;
2595 constexpr uint8_t activeComponentVersionStringLength = 8;
2596 constexpr uint8_t pendingComponentVersionStringLength = 9;
2597 constexpr size_t downstreamDeviceParamTableLen =
2598 static_cast<size_t>(downstreamDeviceCount *
2599 (PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
2600 activeComponentVersionStringLength +
2601 pendingComponentVersionStringLength));
2602 constexpr uint8_t completion_code_resp = PLDM_SUCCESS;
2603 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2604 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2605 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2606 constexpr size_t payload_len =
2607 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
2608 downstreamDeviceParamTableLen;
2609
2610 PLDM_MSG_DEFINE_P(response, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302611 PLDM_MSGBUF_DEFINE_P(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302612 int rc = 0;
2613
2614 rc = pldm_msgbuf_init_errno(buf, 0, response->payload, payload_len);
Andrew Jefferya1896962025-03-03 21:41:25 +10302615 ASSERT_EQ(rc, 0);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302616
2617 // Table 24
2618 pldm_msgbuf_insert_uint8(buf, completion_code_resp);
2619 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2620 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2621
2622 // Table 25
2623 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2624 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
2625
2626 constexpr const std::array<pldm_downstream_device_parameters_entry, 2>
2627 table = {{{
2628 0,
2629 0,
2630 1,
2631 8,
2632 "20241206",
2633 0,
2634 1,
2635 9,
2636 "20241209",
2637 {1},
2638 {0},
2639 "active_0",
2640 "pending_0",
2641 },
2642 {
2643 1,
2644 0,
2645 1,
2646 8,
2647 "20241209",
2648 0,
2649 1,
2650 9,
2651 "20241206",
2652 {1},
2653 {0},
2654 "active_1",
2655 "pending_1",
2656 }}};
2657 for (const auto& e : table)
2658 {
2659 // Table 26
2660 pldm_msgbuf_insert_uint16(buf, e.downstream_device_index);
2661
2662 // - Active metadata
2663 pldm_msgbuf_insert_uint32(buf, e.active_comp_comparison_stamp);
2664 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_type);
2665 pldm_msgbuf_insert_uint8(buf, e.active_comp_ver_str_len);
2666 rc = pldm__msgbuf_insert_array_void(buf, 8, &e.active_comp_release_date,
2667 sizeof(e.active_comp_release_date));
2668 ASSERT_EQ(rc, 0);
2669
2670 // - Pending metadata
2671 pldm_msgbuf_insert_uint32(buf, e.pending_comp_comparison_stamp);
2672 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_type);
2673 pldm_msgbuf_insert_uint8(buf, e.pending_comp_ver_str_len);
2674 rc =
2675 pldm__msgbuf_insert_array_void(buf, 8, e.pending_comp_release_date,
2676 sizeof(e.pending_comp_release_date));
2677 ASSERT_EQ(rc, 0);
2678
2679 // - Methods and capabilities
2680 pldm_msgbuf_insert_uint16(buf, e.comp_activation_methods.value);
2681 pldm_msgbuf_insert_uint32(buf, e.capabilities_during_update.value);
2682
2683 // - Version strings
2684 rc = pldm__msgbuf_insert_array_void(buf, e.active_comp_ver_str_len,
2685 e.active_comp_ver_str,
2686 e.active_comp_ver_str_len);
2687 ASSERT_EQ(rc, 0);
2688 rc = pldm__msgbuf_insert_array_void(buf, e.pending_comp_ver_str_len,
2689 e.pending_comp_ver_str,
2690 e.pending_comp_ver_str_len);
2691 ASSERT_EQ(rc, 0);
2692 }
2693
Andrew Jeffery70d21c92025-03-05 12:59:42 +10302694 rc = pldm_msgbuf_complete_consumed(buf);
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302695 ASSERT_EQ(rc, 0);
2696
2697 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
2698 struct pldm_downstream_device_parameters_iter iter = {};
2699
2700 rc = decode_get_downstream_firmware_parameters_resp(response, payload_len,
2701 &resp_data, &iter);
2702
2703 ASSERT_EQ(rc, 0);
2704 EXPECT_EQ(resp_data.completion_code, completion_code_resp);
2705 EXPECT_EQ(resp_data.next_data_transfer_handle,
2706 next_data_transfer_handle_resp);
2707 EXPECT_EQ(resp_data.transfer_flag, transfer_flag_resp);
2708 EXPECT_EQ(resp_data.downstream_device_count, downstreamDeviceCount);
2709
2710 struct pldm_downstream_device_parameters_entry entry;
2711 size_t entryIndex = 0;
2712 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2713 {
2714 ASSERT_LE(entryIndex, table.size());
2715
2716 EXPECT_EQ(table[entryIndex].downstream_device_index,
2717 entry.downstream_device_index);
2718 EXPECT_EQ(table[entryIndex].active_comp_comparison_stamp,
2719 entry.active_comp_comparison_stamp);
2720 EXPECT_EQ(table[entryIndex].active_comp_ver_str_type,
2721 entry.active_comp_ver_str_type);
2722 EXPECT_EQ(table[entryIndex].active_comp_ver_str_len,
2723 entry.active_comp_ver_str_len);
2724 EXPECT_STREQ(&table[entryIndex].active_comp_release_date[0],
2725 &entry.active_comp_release_date[0]);
2726 EXPECT_EQ(table[entryIndex].pending_comp_comparison_stamp,
2727 entry.pending_comp_comparison_stamp);
2728 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_type,
2729 entry.pending_comp_ver_str_type);
2730 EXPECT_EQ(table[entryIndex].pending_comp_ver_str_len,
2731 entry.pending_comp_ver_str_len);
2732 EXPECT_STREQ(&table[entryIndex].pending_comp_release_date[0],
2733 &entry.pending_comp_release_date[0]);
2734 EXPECT_EQ(table[entryIndex].comp_activation_methods.value,
2735 entry.comp_activation_methods.value);
2736 EXPECT_EQ(table[entryIndex].capabilities_during_update.value,
2737 entry.capabilities_during_update.value);
2738 EXPECT_FALSE(memcmp(table[entryIndex].active_comp_ver_str,
2739 entry.active_comp_ver_str,
2740 table[entryIndex].active_comp_ver_str_len));
2741 EXPECT_FALSE(memcmp(table[entryIndex].pending_comp_ver_str,
2742 entry.pending_comp_ver_str,
2743 table[entryIndex].pending_comp_ver_str_len));
2744 entryIndex++;
2745 }
2746 EXPECT_EQ(rc, 0);
2747 EXPECT_EQ(entryIndex, table.size());
Chris Wangb6ef35b2024-07-03 09:35:42 +08002748}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002749
Chris Wangb6ef35b2024-07-03 09:35:42 +08002750TEST(GetDownstreamFirmwareParameters, decodeResponseInvalidLength)
2751{
2752 /** Count is not fixed here taking it as 1, and the downstream device's
2753 * version strings length are set to 8
2754 */
2755 constexpr uint16_t downstreamDeviceCount = 1;
2756 constexpr uint8_t activeComponentVersionStringLength = 8;
2757 constexpr uint8_t pendingComponentVersionStringLength = 8;
2758 constexpr size_t downstreamDeviceParamTableLen =
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302759 PLDM_DOWNSTREAM_DEVICE_PARAMETERS_ENTRY_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002760 activeComponentVersionStringLength +
2761 pendingComponentVersionStringLength;
2762 constexpr uint8_t complition_code_resp = PLDM_SUCCESS;
2763 constexpr uint32_t next_data_transfer_handle_resp = 0x0;
2764 constexpr uint8_t transfer_flag_resp = PLDM_START_AND_END;
2765 constexpr bitfield32_t fdp_capabilities_during_update = {.value = 0x0002};
2766
2767 std::array<uint8_t,
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302768 hdrSize + PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN +
Chris Wangb6ef35b2024-07-03 09:35:42 +08002769 downstreamDeviceParamTableLen - 1 /* inject error length*/>
2770 responseMsg{};
2771
2772 int rc = 0;
2773
Andrew Jefferya1896962025-03-03 21:41:25 +10302774 PLDM_MSGBUF_DEFINE_P(buf);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002775 rc = pldm_msgbuf_init_errno(buf, 0, responseMsg.data() + hdrSize,
2776 responseMsg.size() - hdrSize);
Andrew Jefferya1896962025-03-03 21:41:25 +10302777 ASSERT_EQ(rc, 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002778
2779 pldm_msgbuf_insert_uint8(buf, complition_code_resp);
2780 pldm_msgbuf_insert_uint32(buf, next_data_transfer_handle_resp);
2781 pldm_msgbuf_insert_uint8(buf, transfer_flag_resp);
2782 pldm_msgbuf_insert_uint32(buf, fdp_capabilities_during_update.value);
2783 pldm_msgbuf_insert_uint16(buf, downstreamDeviceCount);
Andrew Jefferya1896962025-03-03 21:41:25 +10302784 ASSERT_EQ(pldm_msgbuf_complete(buf), 0);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002785
2786 /** Filling paramter table, the correctness of the downstream devices data
2787 * is not checked in this test case so filling with 0xff
2788 */
2789 std::fill_n(responseMsg.data() + hdrSize +
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302790 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_RESP_MIN_LEN,
Chris Wangb6ef35b2024-07-03 09:35:42 +08002791 downstreamDeviceParamTableLen - 1 /* inject error length*/,
2792 0xff);
2793
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302794 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Chris Wangb6ef35b2024-07-03 09:35:42 +08002795 auto response = reinterpret_cast<pldm_msg*>(responseMsg.data());
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302796 struct pldm_get_downstream_firmware_parameters_resp resp_data = {};
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302797 struct pldm_downstream_device_parameters_iter iter;
Chris Wangb6ef35b2024-07-03 09:35:42 +08002798
Andrew Jeffery6a97b792024-12-09 13:46:51 +10302799 rc = decode_get_downstream_firmware_parameters_resp(
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302800 response, responseMsg.size() - hdrSize, &resp_data, &iter);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002801 EXPECT_EQ(rc, 0);
2802
Andrew Jeffery5a5129b2024-12-04 16:12:40 +10302803 struct pldm_downstream_device_parameters_entry entry;
2804 foreach_pldm_downstream_device_parameters_entry(iter, entry, rc)
2805 {
2806 FAIL();
2807 }
2808 EXPECT_EQ(rc, -EOVERFLOW);
Chris Wangb6ef35b2024-07-03 09:35:42 +08002809}
Chris Wangb6ef35b2024-07-03 09:35:42 +08002810
Andrew Jeffery9c766792022-08-10 23:12:49 +09302811TEST(RequestUpdate, goodPathEncodeRequest)
2812{
2813 constexpr uint8_t instanceId = 1;
2814 constexpr uint32_t maxTransferSize = 512;
2815 constexpr uint16_t numOfComp = 3;
2816 constexpr uint8_t maxOutstandingTransferReq = 2;
2817 constexpr uint16_t pkgDataLen = 0x1234;
2818 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2819 constexpr uint8_t compImgSetVerStrLen =
2820 static_cast<uint8_t>(compImgSetVerStr.size());
2821 variable_field compImgSetVerStrInfo{};
2822 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302823 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302824 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2825 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2826
2827 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2828 compImgSetVerStrLen>
2829 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302830 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302831 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2832
2833 auto rc = encode_request_update_req(
2834 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2835 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2836 &compImgSetVerStrInfo, requestMsg,
2837 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2838 EXPECT_EQ(rc, PLDM_SUCCESS);
2839
2840 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2841 compImgSetVerStrLen>
2842 outRequest{0x81, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00,
2843 0x02, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65, 0x6e,
2844 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x30};
2845 EXPECT_EQ(request, outRequest);
2846}
2847
2848TEST(RequestUpdate, errorPathEncodeRequest)
2849{
2850 constexpr uint8_t instanceId = 1;
2851 uint32_t maxTransferSize = 512;
2852 constexpr uint16_t numOfComp = 3;
2853 uint8_t maxOutstandingTransferReq = 2;
2854 constexpr uint16_t pkgDataLen = 0x1234;
2855 constexpr std::string_view compImgSetVerStr = "0penBmcv1.0";
2856 uint8_t compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2857 variable_field compImgSetVerStrInfo{};
2858 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302859 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302860 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2861 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2862
2863 std::array<uint8_t, hdrSize + sizeof(struct pldm_request_update_req) +
2864 compImgSetVerStr.size()>
2865 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302866 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302867 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
2868
2869 auto rc = encode_request_update_req(
2870 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2871 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen, nullptr,
2872 requestMsg,
2873 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2874 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2875
2876 compImgSetVerStrInfo.ptr = nullptr;
2877 rc = encode_request_update_req(
2878 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2879 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2880 &compImgSetVerStrInfo, requestMsg,
2881 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2882 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2883 compImgSetVerStrInfo.ptr =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302884 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302885 reinterpret_cast<const uint8_t*>(compImgSetVerStr.data());
2886
2887 rc = encode_request_update_req(
2888 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2889 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2890 &compImgSetVerStrInfo, nullptr,
2891 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2892 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2893
2894 rc = encode_request_update_req(instanceId, maxTransferSize, numOfComp,
2895 maxOutstandingTransferReq, pkgDataLen,
2896 PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2897 &compImgSetVerStrInfo, requestMsg, 0);
2898 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
2899
2900 compImgSetVerStrLen = 0;
2901 rc = encode_request_update_req(
2902 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2903 pkgDataLen, PLDM_STR_TYPE_ASCII, 0, &compImgSetVerStrInfo, nullptr,
2904 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2905 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2906 compImgSetVerStrLen = static_cast<uint8_t>(compImgSetVerStr.size());
2907
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06002908 compImgSetVerStrInfo.length = 0xffff;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302909 rc = encode_request_update_req(
2910 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2911 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2912 &compImgSetVerStrInfo, nullptr,
2913 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2914 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2915 compImgSetVerStrInfo.length = compImgSetVerStrLen;
2916
2917 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE - 1;
2918 rc = encode_request_update_req(
2919 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2920 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2921 &compImgSetVerStrInfo, nullptr,
2922 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2923 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2924 maxTransferSize = PLDM_FWUP_BASELINE_TRANSFER_SIZE;
2925
Andrew Jefferya1cd72b2025-05-09 12:26:06 +09302926 maxOutstandingTransferReq = 0;
Andrew Jeffery9c766792022-08-10 23:12:49 +09302927 rc = encode_request_update_req(
2928 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2929 pkgDataLen, PLDM_STR_TYPE_ASCII, compImgSetVerStrLen,
2930 &compImgSetVerStrInfo, nullptr,
2931 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2932 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2933 maxOutstandingTransferReq = PLDM_FWUP_MIN_OUTSTANDING_REQ;
2934
2935 rc = encode_request_update_req(
2936 instanceId, maxTransferSize, numOfComp, maxOutstandingTransferReq,
2937 pkgDataLen, PLDM_STR_TYPE_UNKNOWN, compImgSetVerStrLen,
2938 &compImgSetVerStrInfo, nullptr,
2939 sizeof(struct pldm_request_update_req) + compImgSetVerStrLen);
2940 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
2941}
2942
2943TEST(RequestUpdate, goodPathDecodeResponse)
2944{
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002945 /* Test a success completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302946 constexpr uint16_t fdMetaDataLen = 1024;
2947 constexpr uint8_t fdWillSendPkgData = 1;
2948 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_request_update_resp)>
2949 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01};
2950
2951 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302952 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302953 reinterpret_cast<const pldm_msg*>(requestUpdateResponse1.data());
2954 uint8_t outCompletionCode = 0;
2955 uint16_t outFdMetaDataLen = 0;
2956 uint8_t outFdWillSendPkgData = 0;
2957
2958 auto rc = decode_request_update_resp(
2959 responseMsg1, requestUpdateResponse1.size() - hdrSize,
2960 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2961 EXPECT_EQ(rc, PLDM_SUCCESS);
2962 EXPECT_EQ(outCompletionCode, PLDM_SUCCESS);
2963 EXPECT_EQ(outFdMetaDataLen, fdMetaDataLen);
2964 EXPECT_EQ(outFdWillSendPkgData, fdWillSendPkgData);
2965
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08002966#ifdef LIBPLDM_API_TESTING
2967 /* Check the success roundtrip matches */
2968 PLDM_MSG_DEFINE_P(enc, 1000);
2969 size_t enc_payload_len = 1000;
2970 const struct pldm_request_update_resp resp_data = {
2971 .completion_code = PLDM_SUCCESS,
2972 .fd_meta_data_len = outFdMetaDataLen,
2973 .fd_will_send_pkg_data = outFdWillSendPkgData,
2974 };
2975 rc = encode_request_update_resp(FIXED_INSTANCE_ID, &resp_data, enc,
2976 &enc_payload_len);
2977 EXPECT_EQ(rc, PLDM_SUCCESS);
2978 EXPECT_EQ(enc_payload_len + hdrSize, requestUpdateResponse1.size());
2979 EXPECT_TRUE(std::equal(requestUpdateResponse1.begin() + hdrSize,
2980 requestUpdateResponse1.end(), enc_buf + hdrSize));
2981 check_response(enc, PLDM_REQUEST_UPDATE);
2982#endif
2983
2984 /* Test a failure completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09302985 outCompletionCode = 0;
2986 outFdMetaDataLen = 0;
2987 outFdWillSendPkgData = 0;
2988
2989 constexpr std::array<uint8_t, hdrSize + sizeof(outCompletionCode)>
2990 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
2991 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09302992 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09302993 reinterpret_cast<const pldm_msg*>(requestUpdateResponse2.data());
2994 rc = decode_request_update_resp(
2995 responseMsg2, requestUpdateResponse2.size() - hdrSize,
2996 &outCompletionCode, &outFdMetaDataLen, &outFdWillSendPkgData);
2997 EXPECT_EQ(rc, PLDM_SUCCESS);
2998 EXPECT_EQ(outCompletionCode, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
2999}
3000
3001TEST(RequestUpdate, errorPathDecodeResponse)
3002{
3003 constexpr std::array<uint8_t,
3004 hdrSize + sizeof(pldm_request_update_resp) - 1>
3005 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
3006
3007 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303008 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303009 reinterpret_cast<const pldm_msg*>(requestUpdateResponse.data());
3010 uint8_t outCompletionCode = 0;
3011 uint16_t outFdMetaDataLen = 0;
3012 uint8_t outFdWillSendPkgData = 0;
3013
3014 auto rc = decode_request_update_resp(
3015 nullptr, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3016 &outFdMetaDataLen, &outFdWillSendPkgData);
3017 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3018
3019 rc = decode_request_update_resp(
3020 responseMsg, requestUpdateResponse.size() - hdrSize, nullptr,
3021 &outFdMetaDataLen, &outFdWillSendPkgData);
3022 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3023
3024 rc = decode_request_update_resp(
3025 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3026 nullptr, &outFdWillSendPkgData);
3027 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3028
3029 rc = decode_request_update_resp(
3030 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3031 &outFdMetaDataLen, nullptr);
3032 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3033
3034 rc = decode_request_update_resp(responseMsg, 0, &outCompletionCode,
3035 &outFdMetaDataLen, &outFdWillSendPkgData);
3036 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3037
3038 rc = decode_request_update_resp(
3039 responseMsg, requestUpdateResponse.size() - hdrSize, &outCompletionCode,
3040 &outFdMetaDataLen, &outFdWillSendPkgData);
3041 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3042}
3043
Sora Su06eadd02025-05-27 11:28:51 +08003044#ifdef LIBPLDM_API_TESTING
3045TEST(RequestDownstreamDeviceUpdate, goodPathEncodeRequest)
3046{
3047 constexpr uint8_t instanceId = 1;
3048
3049 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3050 request{};
3051
3052 auto requestMsg = new (request.data()) pldm_msg;
3053
3054 constexpr struct pldm_request_downstream_device_update_req req_data = {
3055 .maximum_downstream_device_transfer_size = 512,
3056 .maximum_outstanding_transfer_requests = 2,
3057 .downstream_device_package_data_length = 0x1234,
3058 };
3059 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3060
3061 auto rc = encode_request_downstream_device_update_req(
3062 instanceId, &req_data, requestMsg, &enc_payload_len);
3063
3064 EXPECT_EQ(rc, 0);
3065
3066 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3067 outRequest{0x81, 0x05, 0x20, 0x00, 0x02, 0x00, 0x00, 0x02, 0x34, 0x12};
3068 EXPECT_EQ(request, outRequest);
3069}
3070#endif // LIBPLDM_API_TESTING
3071
3072#ifdef LIBPLDM_API_TESTING
3073TEST(RequestDownstreamDeviceUpdate, errorPathEncodeRequest)
3074{
3075 constexpr uint8_t instanceId = 1;
3076 size_t enc_payload_len = PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES;
3077
3078 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES>
3079 request{};
3080
3081 struct pldm_request_downstream_device_update_req req_data = {
3082 .maximum_downstream_device_transfer_size = 512,
3083 .maximum_outstanding_transfer_requests = 2,
3084 .downstream_device_package_data_length = 0x1234,
3085 };
3086
3087 auto requestMsg = new (request.data()) pldm_msg;
3088
3089 auto rc = encode_request_downstream_device_update_req(
3090 instanceId, nullptr, requestMsg, &enc_payload_len);
3091 EXPECT_EQ(rc, -EINVAL);
3092 rc = encode_request_downstream_device_update_req(
3093 instanceId, &req_data, requestMsg, &enc_payload_len);
3094 EXPECT_EQ(rc, 0);
3095
3096 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3097 nullptr, &enc_payload_len);
3098 EXPECT_EQ(rc, -EINVAL);
3099 rc = encode_request_downstream_device_update_req(
3100 instanceId, &req_data, requestMsg, &enc_payload_len);
3101 EXPECT_EQ(rc, 0);
3102
3103 rc = encode_request_downstream_device_update_req(instanceId, &req_data,
3104 requestMsg, nullptr);
3105 EXPECT_EQ(rc, -EINVAL);
3106 rc = encode_request_downstream_device_update_req(
3107 instanceId, &req_data, requestMsg, &enc_payload_len);
3108 EXPECT_EQ(rc, 0);
3109
3110 enc_payload_len =
3111 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES) - 1;
3112 rc = encode_request_downstream_device_update_req(
3113 instanceId, &req_data, requestMsg, &enc_payload_len);
3114 EXPECT_EQ(rc, -EOVERFLOW);
3115 enc_payload_len =
3116 static_cast<size_t>(PLDM_DOWNSTREAM_DEVICE_UPDATE_REQUEST_BYTES);
3117 rc = encode_request_downstream_device_update_req(
3118 instanceId, &req_data, requestMsg, &enc_payload_len);
3119 EXPECT_EQ(rc, 0);
3120
3121 req_data.maximum_downstream_device_transfer_size = 31;
3122 rc = encode_request_downstream_device_update_req(
3123 instanceId, &req_data, requestMsg, &enc_payload_len);
3124 EXPECT_EQ(rc, -EINVAL);
3125 req_data.maximum_downstream_device_transfer_size =
3126 PLDM_FWUP_BASELINE_TRANSFER_SIZE;
3127
3128 req_data.maximum_outstanding_transfer_requests = 0;
3129 rc = encode_request_downstream_device_update_req(
3130 instanceId, &req_data, requestMsg, &enc_payload_len);
3131 EXPECT_EQ(rc, -EINVAL);
3132 req_data.maximum_outstanding_transfer_requests = 2;
3133 rc = encode_request_downstream_device_update_req(
3134 instanceId, &req_data, requestMsg, &enc_payload_len);
3135 EXPECT_EQ(rc, 0);
3136}
3137#endif // LIBPLDM_API_TESTING
3138
3139#ifdef LIBPLDM_API_TESTING
3140TEST(RequestDownstreamDeviceUpdate, goodPathDecodeResponse)
3141{
3142 /* Test a success completion code */
3143 constexpr uint16_t ddMetaDataLen = 1024;
3144 constexpr uint8_t ddWillSendPkgData = 1;
3145 constexpr uint16_t getPkgDataMaxTransferSize = 512;
3146 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3147 requestUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00,
3148 0x04, 0x01, 0x00, 0x02};
3149
3150 auto responseMsg1 = new (requestUpdateResponse1.data()) pldm_msg;
3151
3152 struct pldm_request_downstream_device_update_resp resp_data1 = {
3153 .completion_code = 0,
3154 .downstream_device_meta_data_length = 0,
3155 .downstream_device_will_send_get_package_data = 0,
3156 .get_package_data_maximum_transfer_size = 0};
3157
3158 auto rc = decode_request_downstream_device_update_resp(
3159 responseMsg1, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3160 &resp_data1);
3161 EXPECT_EQ(rc, 0);
3162 EXPECT_EQ(resp_data1.completion_code, PLDM_SUCCESS);
3163 EXPECT_EQ(resp_data1.downstream_device_meta_data_length, ddMetaDataLen);
3164 EXPECT_EQ(resp_data1.downstream_device_will_send_get_package_data,
3165 ddWillSendPkgData);
3166 EXPECT_EQ(resp_data1.get_package_data_maximum_transfer_size,
3167 getPkgDataMaxTransferSize);
3168
3169 /* Test a failure completion code */
3170 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3171 requestUpdateResponse2{0x00, 0x00, 0x00, 0x81};
3172
3173 auto responseMsg2 = new (requestUpdateResponse2.data()) pldm_msg;
3174
3175 struct pldm_request_downstream_device_update_resp resp_data2 = {
3176 .completion_code = 0,
3177 .downstream_device_meta_data_length = 0,
3178 .downstream_device_will_send_get_package_data = 0,
3179 .get_package_data_maximum_transfer_size = 0};
3180
3181 rc = decode_request_downstream_device_update_resp(
3182 responseMsg2, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES,
3183 &resp_data2);
3184 EXPECT_EQ(rc, 0);
3185 EXPECT_EQ(resp_data2.completion_code, PLDM_FWUP_ALREADY_IN_UPDATE_MODE);
3186}
3187#endif // LIBPLDM_API_TESTING
3188
3189#ifdef LIBPLDM_API_TESTING
3190TEST(RequestDownstreamDeviceUpdate, errorPathDecodeResponse)
3191{
3192 std::array<uint8_t, hdrSize + PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES>
3193 requestUpdateResponse{0x00, 0x00, 0x00, 0x00, 0x00,
3194 0x04, 0x01, 0x00, 0x02};
3195
3196 auto responseMsg = new (requestUpdateResponse.data()) pldm_msg;
3197
3198 struct pldm_request_downstream_device_update_resp resp_data = {
3199 .completion_code = 0,
3200 .downstream_device_meta_data_length = 0,
3201 .downstream_device_will_send_get_package_data = 0,
3202 .get_package_data_maximum_transfer_size = 0};
3203
3204 auto rc = decode_request_downstream_device_update_resp(
3205 nullptr, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, &resp_data);
3206 EXPECT_EQ(rc, -EINVAL);
3207
3208 rc = decode_request_downstream_device_update_resp(
3209 responseMsg, PLDM_DOWNSTREAM_DEVICE_UPDATE_RESPONSE_BYTES, nullptr);
3210 EXPECT_EQ(rc, -EINVAL);
3211
3212 rc = decode_request_downstream_device_update_resp(responseMsg, 0,
3213 &resp_data);
3214 EXPECT_EQ(rc, -EOVERFLOW);
3215}
3216#endif // LIBPLDM_API_TESTING
3217
Andrew Jeffery9c766792022-08-10 23:12:49 +09303218TEST(PassComponentTable, goodPathEncodeRequest)
3219{
3220 constexpr uint8_t instanceId = 1;
3221 constexpr uint16_t compIdentifier = 400;
3222 constexpr uint8_t compClassificationIndex = 40;
3223 constexpr uint32_t compComparisonStamp = 0x12345678;
3224 constexpr std::string_view compVerStr = "0penBmcv1.1";
3225 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3226 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303227 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303228 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3229 compVerStrInfo.length = compVerStrLen;
3230
3231 std::array<uint8_t,
3232 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3233 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303234 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303235 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3236
3237 auto rc = encode_pass_component_table_req(
3238 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3239 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3240 compVerStrLen, &compVerStrInfo, requestMsg,
3241 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3242 EXPECT_EQ(rc, PLDM_SUCCESS);
3243
3244 std::array<uint8_t,
3245 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003246 outRequest{0x81, 0x05, 0x13, 0x05, 0x0a, 0x00, 0x90, 0x01, 0x28,
3247 0x78, 0x56, 0x34, 0x12, 0x01, 0x0b, 0x30, 0x70, 0x65,
3248 0x6e, 0x42, 0x6d, 0x63, 0x76, 0x31, 0x2e, 0x31};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303249 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003250
3251#ifdef LIBPLDM_API_TESTING
3252 /* Check the roundtrip */
3253 struct pldm_pass_component_table_req_full req;
3254 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3255 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3256 rc =
3257 decode_pass_component_table_req(dec, outRequest.size() - hdrSize, &req);
3258 ASSERT_EQ(rc, 0);
3259
3260 EXPECT_EQ(req.transfer_flag, PLDM_START_AND_END);
3261 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3262 EXPECT_EQ(req.comp_identifier, compIdentifier);
3263 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3264 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3265 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3266 EXPECT_EQ(req.version.str_len, compVerStrLen);
3267 EXPECT_TRUE(std::equal(req.version.str_data,
3268 req.version.str_data + req.version.str_len,
3269 compVerStr.data()));
3270#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303271}
3272
3273TEST(PassComponentTable, errorPathEncodeRequest)
3274{
3275 constexpr uint8_t instanceId = 1;
3276 constexpr uint16_t compIdentifier = 400;
3277 constexpr uint8_t compClassificationIndex = 40;
3278 constexpr uint32_t compComparisonStamp = 0x12345678;
3279 constexpr std::string_view compVerStr = "0penBmcv1.1";
3280 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3281 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303282 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303283 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3284 compVerStrInfo.length = compVerStrLen;
3285
3286 std::array<uint8_t,
3287 hdrSize + sizeof(pldm_pass_component_table_req) + compVerStrLen>
3288 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303289 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303290 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3291
3292 auto rc = encode_pass_component_table_req(
3293 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3294 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3295 compVerStrLen, nullptr, requestMsg,
3296 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3297 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3298
3299 compVerStrInfo.ptr = nullptr;
3300 rc = encode_pass_component_table_req(
3301 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3302 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3303 compVerStrLen, &compVerStrInfo, requestMsg,
3304 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3305 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303306 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303307 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3308
3309 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, &compVerStrInfo, nullptr,
3313 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3314 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3315
3316 rc = encode_pass_component_table_req(
3317 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3318 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3319 compVerStrLen, &compVerStrInfo, requestMsg,
3320 sizeof(pldm_pass_component_table_req));
3321 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3322
3323 rc = encode_pass_component_table_req(
3324 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3325 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII, 0,
3326 &compVerStrInfo, requestMsg,
3327 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3328 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3329
3330 rc = encode_pass_component_table_req(
3331 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3332 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3333 compVerStrLen - 1, &compVerStrInfo, requestMsg,
3334 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3335 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3336
3337 rc = encode_pass_component_table_req(
3338 instanceId, PLDM_START_AND_END + 1, PLDM_COMP_FIRMWARE, compIdentifier,
3339 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_ASCII,
3340 compVerStrLen, &compVerStrInfo, requestMsg,
3341 sizeof(pldm_pass_component_table_req) + compVerStrLen);
Manojkiran Eda3643e742025-05-19 12:03:54 +05303342 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG);
Andrew Jeffery9c766792022-08-10 23:12:49 +09303343
3344 rc = encode_pass_component_table_req(
3345 instanceId, PLDM_START_AND_END, PLDM_COMP_FIRMWARE, compIdentifier,
3346 compClassificationIndex, compComparisonStamp, PLDM_STR_TYPE_UNKNOWN,
3347 compVerStrLen, &compVerStrInfo, requestMsg,
3348 sizeof(pldm_pass_component_table_req) + compVerStrLen);
3349 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3350}
3351
3352TEST(PassComponentTable, goodPathDecodeResponse)
3353{
3354 constexpr std::array<uint8_t,
3355 hdrSize + sizeof(pldm_pass_component_table_resp)>
3356 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
3357 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303358 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303359 reinterpret_cast<const pldm_msg*>(passCompTableResponse1.data());
3360
3361 uint8_t completionCode = 0;
3362 uint8_t compResp = 0;
3363 uint8_t compRespCode = 0;
3364
3365 auto rc = decode_pass_component_table_resp(
3366 responseMsg1, sizeof(pldm_pass_component_table_resp), &completionCode,
3367 &compResp, &compRespCode);
3368
3369 EXPECT_EQ(rc, PLDM_SUCCESS);
3370 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3371 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3372 EXPECT_EQ(compRespCode, PLDM_CRC_COMP_COMPARISON_STAMP_IDENTICAL);
3373
3374 constexpr std::array<uint8_t,
3375 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003376 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0xd0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303377 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303378 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303379 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3380 rc = decode_pass_component_table_resp(
3381 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3382 &compResp, &compRespCode);
3383
3384 EXPECT_EQ(rc, PLDM_SUCCESS);
3385 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3386 EXPECT_EQ(compResp, PLDM_CR_COMP_CAN_BE_UPDATED);
3387 EXPECT_EQ(compRespCode, PLDM_CRC_VENDOR_COMP_RESP_CODE_RANGE_MIN);
3388
3389 constexpr std::array<uint8_t,
3390 hdrSize + sizeof(pldm_pass_component_table_resp)>
3391 passCompTableResponse3{0x00, 0x00, 0x00, 0x80};
3392 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303393 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303394 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3395
3396 rc = decode_pass_component_table_resp(
3397 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3398 &compResp, &compRespCode);
3399
3400 EXPECT_EQ(rc, PLDM_SUCCESS);
3401 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3402}
3403
3404TEST(PassComponentTable, errorPathDecodeResponse)
3405{
3406 constexpr std::array<uint8_t,
3407 hdrSize + sizeof(pldm_pass_component_table_resp) - 1>
3408 passCompTableResponse1{0x00, 0x00, 0x00, 0x00, 0x00};
3409 auto responseMsg1 =
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*>(passCompTableResponse1.data());
3412
3413 uint8_t completionCode = 0;
3414 uint8_t compResp = 0;
3415 uint8_t compRespCode = 0;
3416
3417 auto rc = decode_pass_component_table_resp(
3418 nullptr, sizeof(pldm_pass_component_table_resp) - 1, &completionCode,
3419 &compResp, &compRespCode);
3420 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3421
3422 rc = decode_pass_component_table_resp(
3423 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1, nullptr,
3424 &compResp, &compRespCode);
3425 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3426
3427 rc = decode_pass_component_table_resp(
3428 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3429 &completionCode, nullptr, &compRespCode);
3430 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3431
3432 rc = decode_pass_component_table_resp(
3433 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3434 &completionCode, &compResp, nullptr);
3435 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3436
3437 rc = decode_pass_component_table_resp(responseMsg1, 0, &completionCode,
3438 &compResp, &compRespCode);
3439 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3440
3441 rc = decode_pass_component_table_resp(
3442 responseMsg1, sizeof(pldm_pass_component_table_resp) - 1,
3443 &completionCode, &compResp, &compRespCode);
3444 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3445
3446 constexpr std::array<uint8_t,
3447 hdrSize + sizeof(pldm_pass_component_table_resp)>
3448 passCompTableResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
3449 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303450 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303451 reinterpret_cast<const pldm_msg*>(passCompTableResponse2.data());
3452 rc = decode_pass_component_table_resp(
3453 responseMsg2, sizeof(pldm_pass_component_table_resp), &completionCode,
3454 &compResp, &compRespCode);
3455 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3456
3457 constexpr std::array<uint8_t,
3458 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003459 passCompTableResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303460 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303461 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303462 reinterpret_cast<const pldm_msg*>(passCompTableResponse3.data());
3463 rc = decode_pass_component_table_resp(
3464 responseMsg3, sizeof(pldm_pass_component_table_resp), &completionCode,
3465 &compResp, &compRespCode);
3466 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3467
3468 constexpr std::array<uint8_t,
3469 hdrSize + sizeof(pldm_pass_component_table_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003470 passCompTableResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303471 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303472 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303473 reinterpret_cast<const pldm_msg*>(passCompTableResponse4.data());
3474 rc = decode_pass_component_table_resp(
3475 responseMsg4, sizeof(pldm_pass_component_table_resp), &completionCode,
3476 &compResp, &compRespCode);
3477 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3478}
3479
3480TEST(UpdateComponent, goodPathEncodeRequest)
3481{
3482 constexpr uint8_t instanceId = 2;
3483 constexpr uint16_t compIdentifier = 500;
3484 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003485 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303486 constexpr uint32_t compImageSize = 4096;
3487 constexpr bitfield32_t updateOptionFlags{1};
3488 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3489 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3490 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303491 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303492 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3493 compVerStrInfo.length = compVerStrLen;
3494
3495 std::array<uint8_t,
3496 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3497 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303498 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303499 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3500
3501 auto rc = encode_update_component_req(
3502 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3503 compComparisonStamp, compImageSize, updateOptionFlags,
3504 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3505 sizeof(pldm_update_component_req) + compVerStrLen);
3506 EXPECT_EQ(rc, PLDM_SUCCESS);
3507
3508 std::array<uint8_t,
3509 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003510 outRequest{0x82, 0x05, 0x14, 0x0a, 0x00, 0xf4, 0x01, 0x32, 0xef,
3511 0xcd, 0xab, 0x89, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00,
3512 0x00, 0x00, 0x01, 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x42,
3513 0x6d, 0x63, 0x76, 0x32, 0x2e, 0x32};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303514 EXPECT_EQ(request, outRequest);
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08003515
3516#ifdef LIBPLDM_API_TESTING
3517 /* Check the roundtrip */
3518 struct pldm_update_component_req_full req;
3519 PLDM_MSG_DEFINE_P(dec, outRequest.size());
3520 std::copy(outRequest.begin(), outRequest.end(), dec_buf);
3521 rc = decode_update_component_req(dec, outRequest.size() - hdrSize, &req);
3522 ASSERT_EQ(rc, 0);
3523
3524 EXPECT_EQ(req.comp_classification, PLDM_COMP_FIRMWARE);
3525 EXPECT_EQ(req.comp_identifier, compIdentifier);
3526 EXPECT_EQ(req.comp_classification_index, compClassificationIndex);
3527 EXPECT_EQ(req.comp_comparison_stamp, compComparisonStamp);
3528 EXPECT_EQ(req.comp_image_size, compImageSize);
3529 EXPECT_EQ(req.update_option_flags.value, updateOptionFlags.value);
3530 EXPECT_EQ(req.version.str_type, PLDM_STR_TYPE_ASCII);
3531 EXPECT_EQ(req.version.str_len, compVerStrLen);
3532 EXPECT_TRUE(std::equal(req.version.str_data,
3533 req.version.str_data + req.version.str_len,
3534 compVerStr.data()));
3535#endif
Andrew Jeffery9c766792022-08-10 23:12:49 +09303536}
3537
3538TEST(UpdateComponent, errorPathEncodeRequest)
3539{
3540 constexpr uint8_t instanceId = 2;
3541 constexpr uint16_t compIdentifier = 500;
3542 constexpr uint8_t compClassificationIndex = 50;
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003543 constexpr uint32_t compComparisonStamp = 0x89abcdef;
Andrew Jeffery9c766792022-08-10 23:12:49 +09303544 constexpr uint32_t compImageSize = 4096;
3545 constexpr bitfield32_t updateOptionFlags{1};
3546 constexpr std::string_view compVerStr = "OpenBmcv2.2";
3547 constexpr uint8_t compVerStrLen = static_cast<uint8_t>(compVerStr.size());
3548 variable_field compVerStrInfo{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303549 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303550 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3551 compVerStrInfo.length = compVerStrLen;
3552
3553 std::array<uint8_t,
3554 hdrSize + sizeof(pldm_update_component_req) + compVerStrLen>
3555 request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303556 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303557 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
3558
3559 auto rc = encode_update_component_req(
3560 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3561 compComparisonStamp, compImageSize, updateOptionFlags,
3562 PLDM_STR_TYPE_ASCII, compVerStrLen, nullptr, requestMsg,
3563 sizeof(pldm_update_component_req) + compVerStrLen);
3564 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3565
3566 compVerStrInfo.ptr = nullptr;
3567 rc = encode_update_component_req(
3568 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3569 compComparisonStamp, compImageSize, updateOptionFlags,
3570 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3571 sizeof(pldm_update_component_req) + compVerStrLen);
3572 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303573 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303574 compVerStrInfo.ptr = reinterpret_cast<const uint8_t*>(compVerStr.data());
3575
3576 rc = encode_update_component_req(
3577 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3578 compComparisonStamp, compImageSize, updateOptionFlags,
3579 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, nullptr,
3580 sizeof(pldm_update_component_req) + compVerStrLen);
3581 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3582
3583 rc = encode_update_component_req(
3584 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3585 compComparisonStamp, compImageSize, updateOptionFlags,
3586 PLDM_STR_TYPE_ASCII, compVerStrLen, &compVerStrInfo, requestMsg,
3587 sizeof(pldm_update_component_req));
3588 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3589
3590 rc = encode_update_component_req(
3591 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3592 compComparisonStamp, 0, updateOptionFlags, PLDM_STR_TYPE_ASCII,
3593 compVerStrLen, &compVerStrInfo, requestMsg,
3594 sizeof(pldm_update_component_req) + compVerStrLen);
3595 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3596
3597 rc = encode_update_component_req(
3598 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3599 compComparisonStamp, compImageSize, updateOptionFlags,
3600 PLDM_STR_TYPE_ASCII, 0, &compVerStrInfo, requestMsg,
3601 sizeof(pldm_update_component_req) + compVerStrLen);
3602 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3603
3604 rc = encode_update_component_req(
3605 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3606 compComparisonStamp, compImageSize, updateOptionFlags,
3607 PLDM_STR_TYPE_ASCII, compVerStrLen - 1, &compVerStrInfo, requestMsg,
3608 sizeof(pldm_update_component_req) + compVerStrLen);
3609 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3610
3611 rc = encode_update_component_req(
3612 instanceId, PLDM_COMP_FIRMWARE, compIdentifier, compClassificationIndex,
3613 compComparisonStamp, compImageSize, updateOptionFlags,
3614 PLDM_STR_TYPE_UNKNOWN, compVerStrLen, &compVerStrInfo, requestMsg,
3615 sizeof(pldm_update_component_req) + compVerStrLen);
3616 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3617}
3618
3619TEST(UpdateComponent, goodPathDecodeResponse)
3620{
3621 constexpr std::bitset<32> forceUpdateComp{1};
3622 constexpr uint16_t timeBeforeSendingReqFwData100s = 100;
3623 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3624 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3625 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3626 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303627 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303628 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3629
3630 uint8_t completionCode = 0;
3631 uint8_t compCompatibilityResp = 0;
3632 uint8_t compCompatibilityRespCode = 0;
3633 bitfield32_t updateOptionFlagsEnabled{};
3634 uint16_t timeBeforeReqFWData = 0;
3635
3636 auto rc = decode_update_component_resp(
3637 responseMsg1, sizeof(pldm_update_component_resp), &completionCode,
3638 &compCompatibilityResp, &compCompatibilityRespCode,
3639 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3640
3641 EXPECT_EQ(rc, PLDM_SUCCESS);
3642 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3643 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CAN_BE_UPDATED);
3644 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_NO_RESPONSE_CODE);
3645 EXPECT_EQ(updateOptionFlagsEnabled.value, forceUpdateComp);
3646 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData100s);
3647
3648 constexpr std::bitset<32> noFlags{};
3649 constexpr uint16_t timeBeforeSendingReqFwData0s = 0;
3650 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3651 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
3653 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303654 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303655 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3656 rc = decode_update_component_resp(
3657 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3658 &compCompatibilityResp, &compCompatibilityRespCode,
3659 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3660
3661 EXPECT_EQ(rc, PLDM_SUCCESS);
3662 EXPECT_EQ(completionCode, PLDM_SUCCESS);
3663 EXPECT_EQ(compCompatibilityResp, PLDM_CCR_COMP_CANNOT_BE_UPDATED);
3664 EXPECT_EQ(compCompatibilityRespCode, PLDM_CCRC_COMP_INFO_NO_MATCH);
3665 EXPECT_EQ(updateOptionFlagsEnabled.value, noFlags);
3666 EXPECT_EQ(timeBeforeReqFWData, timeBeforeSendingReqFwData0s);
3667
3668 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3669 updateComponentResponse3{0x00, 0x00, 0x00, 0x80};
3670 auto responseMsg3 =
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*>(updateComponentResponse3.data());
3673
3674 rc = decode_update_component_resp(
3675 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3676 &compCompatibilityResp, &compCompatibilityRespCode,
3677 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3678
3679 EXPECT_EQ(rc, PLDM_SUCCESS);
3680 EXPECT_EQ(completionCode, PLDM_FWUP_NOT_IN_UPDATE_MODE);
3681}
3682
3683TEST(UpdateComponent, errorPathDecodeResponse)
3684{
3685 constexpr std::array<uint8_t,
3686 hdrSize + sizeof(pldm_update_component_resp) - 1>
3687 updateComponentResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x09,
3688 0x00, 0x00, 0x00, 0x00, 0x00};
3689 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303690 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303691 reinterpret_cast<const pldm_msg*>(updateComponentResponse1.data());
3692
3693 uint8_t completionCode = 0;
3694 uint8_t compCompatibilityResp = 0;
3695 uint8_t compCompatibilityRespCode = 0;
3696 bitfield32_t updateOptionFlagsEnabled{};
3697 uint16_t timeBeforeReqFWData = 0;
3698
3699 auto rc = decode_update_component_resp(
3700 nullptr, sizeof(pldm_update_component_resp) - 1, &completionCode,
3701 &compCompatibilityResp, &compCompatibilityRespCode,
3702 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3703 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3704
3705 rc = decode_update_component_resp(
3706 responseMsg1, sizeof(pldm_update_component_resp) - 1, nullptr,
3707 &compCompatibilityResp, &compCompatibilityRespCode,
3708 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3709 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3710
3711 rc = decode_update_component_resp(
3712 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3713 nullptr, &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3714 &timeBeforeReqFWData);
3715 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3716
3717 rc = decode_update_component_resp(
3718 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3719 &compCompatibilityResp, nullptr, &updateOptionFlagsEnabled,
3720 &timeBeforeReqFWData);
3721 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3722
3723 rc = decode_update_component_resp(
3724 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3725 &compCompatibilityResp, &compCompatibilityRespCode, nullptr,
3726 &timeBeforeReqFWData);
3727 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3728
3729 rc = decode_update_component_resp(
3730 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3731 &compCompatibilityResp, &compCompatibilityRespCode,
3732 &updateOptionFlagsEnabled, nullptr);
3733 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3734
3735 rc = decode_update_component_resp(
3736 responseMsg1, 0, &completionCode, &compCompatibilityResp,
3737 &compCompatibilityRespCode, &updateOptionFlagsEnabled,
3738 &timeBeforeReqFWData);
3739 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3740
3741 rc = decode_update_component_resp(
3742 responseMsg1, sizeof(pldm_update_component_resp) - 1, &completionCode,
3743 &compCompatibilityResp, &compCompatibilityRespCode,
3744 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3745 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3746
3747 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
3748 updateComponentResponse2{0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
3749 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3750 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303751 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303752 reinterpret_cast<const pldm_msg*>(updateComponentResponse2.data());
3753 rc = decode_update_component_resp(
3754 responseMsg2, sizeof(pldm_update_component_resp), &completionCode,
3755 &compCompatibilityResp, &compCompatibilityRespCode,
3756 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3757 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3758
3759 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003760 updateComponentResponse3{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303761 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3762 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303763 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303764 reinterpret_cast<const pldm_msg*>(updateComponentResponse3.data());
3765 rc = decode_update_component_resp(
3766 responseMsg3, sizeof(pldm_update_component_resp), &completionCode,
3767 &compCompatibilityResp, &compCompatibilityRespCode,
3768 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3769 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3770
3771 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_update_component_resp)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003772 updateComponentResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
Andrew Jeffery9c766792022-08-10 23:12:49 +09303773 0x01, 0x00, 0x00, 0x00, 0x64, 0x00};
3774 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303775 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303776 reinterpret_cast<const pldm_msg*>(updateComponentResponse4.data());
3777 rc = decode_update_component_resp(
3778 responseMsg4, sizeof(pldm_update_component_resp), &completionCode,
3779 &compCompatibilityResp, &compCompatibilityRespCode,
3780 &updateOptionFlagsEnabled, &timeBeforeReqFWData);
3781 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3782}
3783
3784TEST(RequestFirmwareData, goodPathDecodeRequest)
3785{
3786 constexpr uint32_t offset = 300;
3787 constexpr uint32_t length = 255;
3788 constexpr std::array<uint8_t,
3789 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003790 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3791 0x00, 0xff, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303792 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303793 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3794
3795 uint32_t outOffset = 0;
3796 uint32_t outLength = 0;
3797 auto rc = decode_request_firmware_data_req(
3798 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3799 &outLength);
3800
3801 EXPECT_EQ(rc, PLDM_SUCCESS);
3802 EXPECT_EQ(outOffset, offset);
3803 EXPECT_EQ(outLength, length);
3804}
3805
3806TEST(RequestFirmwareData, errorPathDecodeRequest)
3807{
3808 constexpr std::array<uint8_t,
3809 hdrSize + sizeof(pldm_request_firmware_data_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003810 reqFWDataReq{0x00, 0x00, 0x00, 0x2c, 0x01, 0x00,
3811 0x00, 0x1f, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303812 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303813 auto requestMsg = reinterpret_cast<const pldm_msg*>(reqFWDataReq.data());
3814
3815 uint32_t outOffset = 0;
3816 uint32_t outLength = 0;
3817 auto rc = decode_request_firmware_data_req(
3818 nullptr, sizeof(pldm_request_firmware_data_req), &outOffset,
3819 &outLength);
3820 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3821
3822 rc = decode_request_firmware_data_req(
3823 requestMsg, sizeof(pldm_request_firmware_data_req), nullptr,
3824 &outLength);
3825 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3826
3827 rc = decode_request_firmware_data_req(
3828 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3829 nullptr);
3830 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3831
3832 rc = decode_request_firmware_data_req(
3833 requestMsg, sizeof(pldm_request_firmware_data_req) - 1, &outOffset,
3834 &outLength);
3835 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3836
3837 rc = decode_request_firmware_data_req(
3838 requestMsg, sizeof(pldm_request_firmware_data_req), &outOffset,
3839 &outLength);
3840 EXPECT_EQ(rc, PLDM_FWUP_INVALID_TRANSFER_LENGTH);
3841}
3842
3843TEST(RequestFirmwareData, goodPathEncodeResponse)
3844{
3845 constexpr uint8_t instanceId = 3;
3846 constexpr uint8_t completionCode = PLDM_SUCCESS;
3847 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode) +
3848 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3849 outReqFwDataResponse1{0x03, 0x05, 0x15, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003850 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3851 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3852 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3853 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jeffery9c766792022-08-10 23:12:49 +09303854 std::array<uint8_t, hdrSize + sizeof(completionCode) +
3855 PLDM_FWUP_BASELINE_TRANSFER_SIZE>
3856 reqFwDataResponse1{0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06003857 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
3858 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
3859 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
3860 0x1d, 0x1e, 0x1f, 0x20};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303861 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303862 auto responseMsg1 = reinterpret_cast<pldm_msg*>(reqFwDataResponse1.data());
3863 auto rc = encode_request_firmware_data_resp(
3864 instanceId, completionCode, responseMsg1,
3865 sizeof(completionCode) + PLDM_FWUP_BASELINE_TRANSFER_SIZE);
3866 EXPECT_EQ(rc, PLDM_SUCCESS);
3867 EXPECT_EQ(reqFwDataResponse1, outReqFwDataResponse1);
3868
3869 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3870 outReqFwDataResponse2{0x03, 0x05, 0x15, 0x82};
3871 std::array<uint8_t, hdrSize + sizeof(completionCode)> reqFwDataResponse2{
3872 0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303873 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303874 auto responseMsg2 = reinterpret_cast<pldm_msg*>(reqFwDataResponse2.data());
3875 rc = encode_request_firmware_data_resp(
3876 instanceId, PLDM_FWUP_DATA_OUT_OF_RANGE, responseMsg2,
3877 sizeof(completionCode));
3878 EXPECT_EQ(rc, PLDM_SUCCESS);
3879 EXPECT_EQ(reqFwDataResponse2, outReqFwDataResponse2);
3880}
3881
3882TEST(RequestFirmwareData, errorPathEncodeResponse)
3883{
3884 std::array<uint8_t, hdrSize> reqFwDataResponse{0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303885 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303886 auto responseMsg = reinterpret_cast<pldm_msg*>(reqFwDataResponse.data());
3887 auto rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, nullptr, 0);
3888 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3889
3890 rc = encode_request_firmware_data_resp(0, PLDM_SUCCESS, responseMsg, 0);
3891 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3892}
3893
3894TEST(TransferComplete, goodPathDecodeRequest)
3895{
3896 constexpr uint8_t transferResult = PLDM_FWUP_TRANSFER_SUCCESS;
3897 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3898 transferCompleteReq1{0x00, 0x00, 0x00, 0x00};
3899 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303900 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303901 reinterpret_cast<const pldm_msg*>(transferCompleteReq1.data());
3902 uint8_t outTransferResult = 0;
3903
3904 auto rc = decode_transfer_complete_req(requestMsg1, sizeof(transferResult),
3905 &outTransferResult);
3906 EXPECT_EQ(rc, PLDM_SUCCESS);
3907 EXPECT_EQ(outTransferResult, transferResult);
3908
3909 constexpr std::array<uint8_t, hdrSize + sizeof(transferResult)>
3910 transferCompleteReq2{0x00, 0x00, 0x00, 0x02};
3911 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303912 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303913 reinterpret_cast<const pldm_msg*>(transferCompleteReq2.data());
3914 rc = decode_transfer_complete_req(requestMsg2, sizeof(transferResult),
3915 &outTransferResult);
3916 EXPECT_EQ(rc, PLDM_SUCCESS);
3917 EXPECT_EQ(outTransferResult, PLDM_FWUP_TRANSFER_ERROR_IMAGE_CORRUPT);
3918}
3919
3920TEST(TransferComplete, errorPathDecodeRequest)
3921{
3922 constexpr std::array<uint8_t, hdrSize> transferCompleteReq{0x00, 0x00,
3923 0x00};
3924 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303925 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303926 reinterpret_cast<const pldm_msg*>(transferCompleteReq.data());
3927 uint8_t outTransferResult = 0;
3928
3929 auto rc = decode_transfer_complete_req(nullptr, 0, &outTransferResult);
3930 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3931
3932 rc = decode_transfer_complete_req(requestMsg, 0, nullptr);
3933 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3934
3935 rc = decode_transfer_complete_req(requestMsg, 0, &outTransferResult);
3936 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3937}
3938
3939TEST(TransferComplete, goodPathEncodeResponse)
3940{
3941 constexpr uint8_t instanceId = 4;
3942 constexpr uint8_t completionCode = PLDM_SUCCESS;
3943 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3944 outTransferCompleteResponse1{0x04, 0x05, 0x16, 0x00};
3945 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3946 transferCompleteResponse1{0x00, 0x00, 0x00, 0x00};
3947 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303948 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303949 reinterpret_cast<pldm_msg*>(transferCompleteResponse1.data());
3950 auto rc = encode_transfer_complete_resp(
3951 instanceId, completionCode, responseMsg1, sizeof(completionCode));
3952 EXPECT_EQ(rc, PLDM_SUCCESS);
3953 EXPECT_EQ(transferCompleteResponse1, outTransferCompleteResponse1);
3954
3955 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
3956 outTransferCompleteResponse2{0x04, 0x05, 0x16, 0x88};
3957 std::array<uint8_t, hdrSize + sizeof(completionCode)>
3958 transferCompleteResponse2{0x00, 0x00, 0x00, 0x00};
3959 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303960 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303961 reinterpret_cast<pldm_msg*>(transferCompleteResponse2.data());
3962 rc = encode_transfer_complete_resp(instanceId,
3963 PLDM_FWUP_COMMAND_NOT_EXPECTED,
3964 responseMsg2, sizeof(completionCode));
3965 EXPECT_EQ(rc, PLDM_SUCCESS);
3966 EXPECT_EQ(transferCompleteResponse2, outTransferCompleteResponse2);
3967}
3968
3969TEST(TransferComplete, errorPathEncodeResponse)
3970{
3971 std::array<uint8_t, hdrSize> transferCompleteResponse{0x00, 0x00, 0x00};
3972 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303973 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303974 reinterpret_cast<pldm_msg*>(transferCompleteResponse.data());
3975 auto rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
3976 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
3977
3978 rc = encode_transfer_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
3979 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
3980}
3981
3982TEST(VerifyComplete, goodPathDecodeRequest)
3983{
3984 constexpr uint8_t verifyResult = PLDM_FWUP_VERIFY_SUCCESS;
3985 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3986 verifyCompleteReq1{0x00, 0x00, 0x00, 0x00};
3987 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09303988 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09303989 reinterpret_cast<const pldm_msg*>(verifyCompleteReq1.data());
3990 uint8_t outVerifyResult = 0;
3991
3992 auto rc = decode_verify_complete_req(requestMsg1, sizeof(verifyResult),
3993 &outVerifyResult);
3994 EXPECT_EQ(rc, PLDM_SUCCESS);
3995 EXPECT_EQ(outVerifyResult, verifyResult);
3996
3997 constexpr std::array<uint8_t, hdrSize + sizeof(verifyResult)>
3998 verifyCompleteReq2{0x00, 0x00, 0x00, 0x03};
3999 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304000 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304001 reinterpret_cast<const pldm_msg*>(verifyCompleteReq2.data());
4002 rc = decode_verify_complete_req(requestMsg2, sizeof(verifyResult),
4003 &outVerifyResult);
4004 EXPECT_EQ(rc, PLDM_SUCCESS);
4005 EXPECT_EQ(outVerifyResult, PLDM_FWUP_VERIFY_FAILED_FD_SECURITY_CHECKS);
4006}
4007
4008TEST(VerifyComplete, errorPathDecodeRequest)
4009{
4010 constexpr std::array<uint8_t, hdrSize> verifyCompleteReq{0x00, 0x00, 0x00};
4011 auto requestMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304012 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304013 reinterpret_cast<const pldm_msg*>(verifyCompleteReq.data());
4014 uint8_t outVerifyResult = 0;
4015
4016 auto rc = decode_verify_complete_req(nullptr, 0, &outVerifyResult);
4017 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4018
4019 rc = decode_verify_complete_req(requestMsg, 0, nullptr);
4020 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4021
4022 rc = decode_verify_complete_req(requestMsg, 0, &outVerifyResult);
4023 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4024}
4025
4026TEST(VerifyComplete, goodPathEncodeResponse)
4027{
4028 constexpr uint8_t instanceId = 5;
4029 constexpr uint8_t completionCode = PLDM_SUCCESS;
4030 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4031 outVerifyCompleteResponse1{0x05, 0x05, 0x17, 0x00};
4032 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4033 verifyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4034 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304035 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304036 reinterpret_cast<pldm_msg*>(verifyCompleteResponse1.data());
4037 auto rc = encode_verify_complete_resp(instanceId, completionCode,
4038 responseMsg1, sizeof(completionCode));
4039 EXPECT_EQ(rc, PLDM_SUCCESS);
4040 EXPECT_EQ(verifyCompleteResponse1, outVerifyCompleteResponse1);
4041
4042 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4043 outVerifyCompleteResponse2{0x05, 0x05, 0x17, 0x88};
4044 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4045 verifyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4046 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304047 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304048 reinterpret_cast<pldm_msg*>(verifyCompleteResponse2.data());
4049 rc = encode_verify_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4050 responseMsg2, sizeof(completionCode));
4051 EXPECT_EQ(rc, PLDM_SUCCESS);
4052 EXPECT_EQ(verifyCompleteResponse2, outVerifyCompleteResponse2);
4053}
4054
4055TEST(VerifyComplete, errorPathEncodeResponse)
4056{
4057 std::array<uint8_t, hdrSize> verifyCompleteResponse{0x00, 0x00, 0x00};
4058 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304059 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304060 reinterpret_cast<pldm_msg*>(verifyCompleteResponse.data());
4061 auto rc = encode_verify_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4062 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4063
4064 rc = encode_verify_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4065 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4066}
4067
4068TEST(ApplyComplete, goodPathDecodeRequest)
4069{
4070 constexpr uint8_t applyResult1 =
4071 PLDM_FWUP_APPLY_SUCCESS_WITH_ACTIVATION_METHOD;
4072 // DC power cycle [Bit position 4] & AC power cycle [Bit position 5]
4073 constexpr std::bitset<16> compActivationModification1{0x30};
4074 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4075 applyCompleteReq1{0x00, 0x00, 0x00, 0x01, 0x30, 0x00};
4076 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304077 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304078 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4079 uint8_t outApplyResult = 0;
4080 bitfield16_t outCompActivationModification{};
4081 auto rc = decode_apply_complete_req(
4082 requestMsg1, sizeof(pldm_apply_complete_req), &outApplyResult,
4083 &outCompActivationModification);
4084 EXPECT_EQ(rc, PLDM_SUCCESS);
4085 EXPECT_EQ(outApplyResult, applyResult1);
4086 EXPECT_EQ(outCompActivationModification.value, compActivationModification1);
4087
4088 constexpr uint8_t applyResult2 = PLDM_FWUP_APPLY_SUCCESS;
4089 constexpr std::bitset<16> compActivationModification2{};
4090 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4091 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4092 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304093 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304094 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4095 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4096 &outApplyResult,
4097 &outCompActivationModification);
4098 EXPECT_EQ(rc, PLDM_SUCCESS);
4099 EXPECT_EQ(outApplyResult, applyResult2);
4100 EXPECT_EQ(outCompActivationModification.value, compActivationModification2);
4101}
4102
4103TEST(ApplyComplete, errorPathDecodeRequest)
4104{
4105 constexpr std::array<uint8_t, hdrSize> applyCompleteReq1{0x00, 0x00, 0x00};
4106 auto requestMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304107 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304108 reinterpret_cast<const pldm_msg*>(applyCompleteReq1.data());
4109 uint8_t outApplyResult = 0;
4110 bitfield16_t outCompActivationModification{};
4111
4112 auto rc = decode_apply_complete_req(
4113 nullptr, sizeof(pldm_apply_complete_req), &outApplyResult,
4114 &outCompActivationModification);
4115 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4116
4117 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4118 nullptr, &outCompActivationModification);
4119 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4120
4121 rc = decode_apply_complete_req(requestMsg1, sizeof(pldm_apply_complete_req),
4122 &outApplyResult, nullptr);
4123 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4124
4125 rc = decode_apply_complete_req(requestMsg1, 0, &outApplyResult,
4126 &outCompActivationModification);
4127 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4128
4129 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_apply_complete_req)>
4130 applyCompleteReq2{0x00, 0x00, 0x00, 0x00, 0x01, 0x00};
4131 auto requestMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304132 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304133 reinterpret_cast<const pldm_msg*>(applyCompleteReq2.data());
4134 rc = decode_apply_complete_req(requestMsg2, sizeof(pldm_apply_complete_req),
4135 &outApplyResult,
4136 &outCompActivationModification);
4137 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4138}
4139
4140TEST(ApplyComplete, goodPathEncodeResponse)
4141{
4142 constexpr uint8_t instanceId = 6;
4143 constexpr uint8_t completionCode = PLDM_SUCCESS;
4144 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4145 outApplyCompleteResponse1{0x06, 0x05, 0x18, 0x00};
4146 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4147 applyCompleteResponse1{0x00, 0x00, 0x00, 0x00};
4148 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304149 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304150 reinterpret_cast<pldm_msg*>(applyCompleteResponse1.data());
4151 auto rc = encode_apply_complete_resp(instanceId, completionCode,
4152 responseMsg1, sizeof(completionCode));
4153 EXPECT_EQ(rc, PLDM_SUCCESS);
4154 EXPECT_EQ(applyCompleteResponse1, outApplyCompleteResponse1);
4155
4156 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4157 outApplyCompleteResponse2{0x06, 0x05, 0x18, 0x88};
4158 std::array<uint8_t, hdrSize + sizeof(completionCode)>
4159 applyCompleteResponse2{0x00, 0x00, 0x00, 0x00};
4160 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304161 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304162 reinterpret_cast<pldm_msg*>(applyCompleteResponse2.data());
4163 rc = encode_apply_complete_resp(instanceId, PLDM_FWUP_COMMAND_NOT_EXPECTED,
4164 responseMsg2, sizeof(completionCode));
4165 EXPECT_EQ(rc, PLDM_SUCCESS);
4166 EXPECT_EQ(applyCompleteResponse2, outApplyCompleteResponse2);
4167}
4168
4169TEST(ApplyComplete, errorPathEncodeResponse)
4170{
4171 std::array<uint8_t, hdrSize> applyCompleteResponse{0x00, 0x00, 0x00};
4172 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304173 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304174 reinterpret_cast<pldm_msg*>(applyCompleteResponse.data());
4175 auto rc = encode_apply_complete_resp(0, PLDM_SUCCESS, nullptr, 0);
4176 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4177
4178 rc = encode_apply_complete_resp(0, PLDM_SUCCESS, responseMsg, 0);
4179 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4180}
4181
4182TEST(ActivateFirmware, goodPathEncodeRequest)
4183{
4184 constexpr uint8_t instanceId = 7;
4185
4186 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304187 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304188 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4189
4190 auto rc = encode_activate_firmware_req(
4191 instanceId, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg,
4192 sizeof(pldm_activate_firmware_req));
4193 EXPECT_EQ(rc, PLDM_SUCCESS);
4194
4195 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)>
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004196 outRequest{0x87, 0x05, 0x1a, 0x01};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304197 EXPECT_EQ(request, outRequest);
4198}
4199
4200TEST(ActivateFirmware, errorPathEncodeRequest)
4201{
4202 std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_req)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304203 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304204 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4205
4206 auto rc = encode_activate_firmware_req(
4207 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, nullptr,
4208 sizeof(pldm_activate_firmware_req));
4209 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4210
4211 rc = encode_activate_firmware_req(
4212 0, PLDM_ACTIVATE_SELF_CONTAINED_COMPONENTS, requestMsg, 0);
4213 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4214
4215 rc = encode_activate_firmware_req(0, 2, requestMsg,
4216 sizeof(pldm_activate_firmware_req));
4217 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4218}
4219
4220TEST(ActivateFirmware, goodPathDecodeResponse)
4221{
4222 constexpr uint16_t estimatedTimeForActivation100s = 100;
4223 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4224 activateFirmwareResponse1{0x00, 0x00, 0x00, 0x00, 0x64, 0x00};
4225 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304226 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304227 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse1.data());
4228
4229 uint8_t completionCode = 0;
4230 uint16_t estimatedTimeForActivation = 0;
4231
4232 auto rc = decode_activate_firmware_resp(
4233 responseMsg1, sizeof(pldm_activate_firmware_resp), &completionCode,
4234 &estimatedTimeForActivation);
4235
4236 EXPECT_EQ(rc, PLDM_SUCCESS);
4237 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4238 EXPECT_EQ(estimatedTimeForActivation, estimatedTimeForActivation100s);
4239
4240 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4241 activateFirmwareResponse2{0x00, 0x00, 0x00, 0x85};
4242 auto responseMsg2 =
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*>(activateFirmwareResponse2.data());
4245
4246 rc = decode_activate_firmware_resp(responseMsg2, sizeof(completionCode),
4247 &completionCode,
4248 &estimatedTimeForActivation);
4249
4250 EXPECT_EQ(rc, PLDM_SUCCESS);
4251 EXPECT_EQ(completionCode, PLDM_FWUP_INCOMPLETE_UPDATE);
4252}
4253
4254TEST(ActivateFirmware, errorPathDecodeResponse)
4255{
4256 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_activate_firmware_resp)>
4257 activateFirmwareResponse{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4258 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304259 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304260 reinterpret_cast<const pldm_msg*>(activateFirmwareResponse.data());
4261
4262 uint8_t completionCode = 0;
4263 uint16_t estimatedTimeForActivation = 0;
4264
4265 auto rc = decode_activate_firmware_resp(
4266 nullptr, sizeof(pldm_activate_firmware_resp), &completionCode,
4267 &estimatedTimeForActivation);
4268 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4269
4270 rc = decode_activate_firmware_resp(responseMsg,
4271 sizeof(pldm_activate_firmware_resp),
4272 nullptr, &estimatedTimeForActivation);
4273 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4274
4275 rc = decode_activate_firmware_resp(responseMsg,
4276 sizeof(pldm_activate_firmware_resp),
4277 &completionCode, nullptr);
4278 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4279
4280 rc = decode_activate_firmware_resp(responseMsg, 0, &completionCode,
4281 &estimatedTimeForActivation);
4282 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4283
4284 rc = decode_activate_firmware_resp(
4285 responseMsg, sizeof(pldm_activate_firmware_resp) - 1, &completionCode,
4286 &estimatedTimeForActivation);
4287 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4288}
4289
4290TEST(GetStatus, goodPathEncodeRequest)
4291{
4292 constexpr uint8_t instanceId = 8;
4293 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304294 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304295 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4296
4297 auto rc = encode_get_status_req(instanceId, requestMsg,
4298 PLDM_GET_STATUS_REQ_BYTES);
4299 EXPECT_EQ(rc, PLDM_SUCCESS);
4300
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004301 constexpr std::array<uint8_t, hdrSize> outRequest{0x88, 0x05, 0x1b};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304302 EXPECT_EQ(request, outRequest);
4303}
4304
4305TEST(GetStatus, errorPathEncodeRequest)
4306{
4307 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304308 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304309 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4310
4311 auto rc = encode_get_status_req(0, nullptr, PLDM_GET_STATUS_REQ_BYTES);
4312 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4313
4314 rc = encode_get_status_req(0, requestMsg, PLDM_GET_STATUS_REQ_BYTES + 1);
4315 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4316}
4317
4318TEST(GetStatus, goodPathDecodeResponse)
4319{
4320 constexpr std::bitset<32> updateOptionFlagsEnabled1{0};
4321 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4322 getStatusResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
4323 0x09, 0x65, 0x05, 0x00, 0x00, 0x00, 0x00};
4324 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304325 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304326 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4327
4328 uint8_t completionCode = 0;
4329 uint8_t currentState = 0;
4330 uint8_t previousState = 0;
4331 uint8_t auxState = 0;
4332 uint8_t auxStateStatus = 0;
4333 uint8_t progressPercent = 0;
4334 uint8_t reasonCode = 0;
4335 bitfield32_t updateOptionFlagsEnabled{0};
4336
4337 auto rc = decode_get_status_resp(
4338 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4339 &currentState, &previousState, &auxState, &auxStateStatus,
4340 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4341
4342 EXPECT_EQ(rc, PLDM_SUCCESS);
4343 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4344 EXPECT_EQ(currentState, PLDM_FD_STATE_IDLE);
4345 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4346 EXPECT_EQ(auxState, PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER);
4347 EXPECT_EQ(auxStateStatus, PLDM_FD_TIMEOUT);
4348 EXPECT_EQ(progressPercent, PLDM_FWUP_MAX_PROGRESS_PERCENT);
4349 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4350 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled1);
4351
4352 // Bit position 0 - Force update of component – FD will perform a force
4353 // update of the component.
4354 constexpr std::bitset<32> updateOptionFlagsEnabled2{1};
4355 constexpr uint8_t progressPercent2 = 50;
4356 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4357 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x04, 0x03, 0x00,
4358 0x70, 0x32, 0x05, 0x01, 0x00, 0x00, 0x00};
4359 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304360 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304361 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4362
4363 rc = decode_get_status_resp(
4364 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4365 &currentState, &previousState, &auxState, &auxStateStatus,
4366 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4367
4368 EXPECT_EQ(rc, PLDM_SUCCESS);
4369 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4370 EXPECT_EQ(currentState, PLDM_FD_STATE_VERIFY);
4371 EXPECT_EQ(previousState, PLDM_FD_STATE_DOWNLOAD);
4372 EXPECT_EQ(auxState, PLDM_FD_OPERATION_IN_PROGRESS);
4373 EXPECT_EQ(auxStateStatus, PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START);
4374 EXPECT_EQ(progressPercent, progressPercent2);
4375 EXPECT_EQ(reasonCode, PLDM_FD_TIMEOUT_DOWNLOAD);
4376 EXPECT_EQ(updateOptionFlagsEnabled.value, updateOptionFlagsEnabled2);
4377
Matt Johnstoncf9a2df2024-11-07 15:29:29 +08004378#ifdef LIBPLDM_API_TESTING
4379 /* Check the roundtrip */
4380 PLDM_MSG_DEFINE_P(enc, 1000);
4381 size_t enc_payload_len = 1000;
4382 const struct pldm_get_status_resp status_enc = {
4383 .completion_code = PLDM_SUCCESS,
4384 .current_state = currentState,
4385 .previous_state = previousState,
4386 .aux_state = auxState,
4387 .aux_state_status = auxStateStatus,
4388 .progress_percent = progressPercent,
4389 .reason_code = reasonCode,
4390 .update_option_flags_enabled = updateOptionFlagsEnabled,
4391 };
4392 rc = encode_get_status_resp(FIXED_INSTANCE_ID, &status_enc, enc,
4393 &enc_payload_len);
4394 EXPECT_EQ(rc, PLDM_SUCCESS);
4395 EXPECT_EQ(enc_payload_len + hdrSize, getStatusResponse2.size());
4396 EXPECT_TRUE(std::equal(getStatusResponse2.begin() + hdrSize,
4397 getStatusResponse2.end(), enc_buf + hdrSize));
4398 check_response(enc, PLDM_GET_STATUS);
4399#endif
4400
4401 /* Check a not-ready completion code */
Andrew Jeffery9c766792022-08-10 23:12:49 +09304402 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4403 getStatusResponse3{0x00, 0x00, 0x00, 0x04};
4404 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304405 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304406 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4407 rc = decode_get_status_resp(
4408 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4409 &currentState, &previousState, &auxState, &auxStateStatus,
4410 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4411 EXPECT_EQ(rc, PLDM_SUCCESS);
4412 EXPECT_EQ(completionCode, PLDM_ERROR_NOT_READY);
4413}
4414
4415TEST(GetStatus, errorPathDecodeResponse)
4416{
4417 uint8_t completionCode = 0;
4418 uint8_t currentState = 0;
4419 uint8_t previousState = 0;
4420 uint8_t auxState = 0;
4421 uint8_t auxStateStatus = 0;
4422 uint8_t progressPercent = 0;
4423 uint8_t reasonCode = 0;
4424 bitfield32_t updateOptionFlagsEnabled{0};
4425
4426 constexpr std::array<uint8_t, hdrSize> getStatusResponse1{0x00, 0x00, 0x00};
4427 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304428 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304429 reinterpret_cast<const pldm_msg*>(getStatusResponse1.data());
4430
4431 auto rc = decode_get_status_resp(
4432 nullptr, getStatusResponse1.size() - hdrSize, &completionCode,
4433 &currentState, &previousState, &auxState, &auxStateStatus,
4434 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4435 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4436
4437 rc = decode_get_status_resp(
4438 responseMsg1, getStatusResponse1.size() - hdrSize, nullptr,
4439 &currentState, &previousState, &auxState, &auxStateStatus,
4440 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4441 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4442
4443 rc = decode_get_status_resp(
4444 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4445 nullptr, &previousState, &auxState, &auxStateStatus, &progressPercent,
4446 &reasonCode, &updateOptionFlagsEnabled);
4447 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4448
4449 rc = decode_get_status_resp(
4450 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4451 &currentState, nullptr, &auxState, &auxStateStatus, &progressPercent,
4452 &reasonCode, &updateOptionFlagsEnabled);
4453 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4454
4455 rc = decode_get_status_resp(
4456 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4457 &currentState, &previousState, nullptr, &auxStateStatus,
4458 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4459 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4460
4461 rc = decode_get_status_resp(
4462 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4463 &currentState, &previousState, &auxState, nullptr, &progressPercent,
4464 &reasonCode, &updateOptionFlagsEnabled);
4465 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4466
4467 rc = decode_get_status_resp(
4468 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4469 &currentState, &previousState, &auxState, &auxStateStatus, nullptr,
4470 &reasonCode, &updateOptionFlagsEnabled);
4471 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4472
4473 rc = decode_get_status_resp(
4474 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4475 &currentState, &previousState, &auxState, &auxStateStatus,
4476 &progressPercent, nullptr, &updateOptionFlagsEnabled);
4477 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4478
4479 rc = decode_get_status_resp(
4480 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4481 &currentState, &previousState, &auxState, &auxStateStatus,
4482 &progressPercent, &reasonCode, nullptr);
4483 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4484
4485 rc = decode_get_status_resp(
4486 responseMsg1, getStatusResponse1.size() - hdrSize, &completionCode,
4487 &currentState, &previousState, &auxState, &auxStateStatus,
4488 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4489 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4490
4491 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp) - 1>
4492 getStatusResponse2{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4494 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304495 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304496 reinterpret_cast<const pldm_msg*>(getStatusResponse2.data());
4497 rc = decode_get_status_resp(
4498 responseMsg2, getStatusResponse2.size() - hdrSize, &completionCode,
4499 &currentState, &previousState, &auxState, &auxStateStatus,
4500 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4501 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4502
4503 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4504 getStatusResponse3{0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
4505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4506 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304507 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304508 reinterpret_cast<const pldm_msg*>(getStatusResponse3.data());
4509 rc = decode_get_status_resp(
4510 responseMsg3, getStatusResponse3.size() - hdrSize, &completionCode,
4511 &currentState, &previousState, &auxState, &auxStateStatus,
4512 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4513 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4514
4515 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4516 getStatusResponse4{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
4517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4518 auto responseMsg4 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304519 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304520 reinterpret_cast<const pldm_msg*>(getStatusResponse4.data());
4521 rc = decode_get_status_resp(
4522 responseMsg4, getStatusResponse4.size() - hdrSize, &completionCode,
4523 &currentState, &previousState, &auxState, &auxStateStatus,
4524 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4525 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4526
4527 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4528 getStatusResponse5{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
4529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4530 auto responseMsg5 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304531 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304532 reinterpret_cast<const pldm_msg*>(getStatusResponse5.data());
4533 rc = decode_get_status_resp(
4534 responseMsg5, getStatusResponse5.size() - hdrSize, &completionCode,
4535 &currentState, &previousState, &auxState, &auxStateStatus,
4536 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4537 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4538
4539 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4540 getStatusResponse6{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004541 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304542 auto responseMsg6 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304543 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304544 reinterpret_cast<const pldm_msg*>(getStatusResponse6.data());
4545 rc = decode_get_status_resp(
4546 responseMsg6, getStatusResponse6.size() - hdrSize, &completionCode,
4547 &currentState, &previousState, &auxState, &auxStateStatus,
4548 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4549 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4550
4551 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4552 getStatusResponse7{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4553 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00};
4554 auto responseMsg7 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304555 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304556 reinterpret_cast<const pldm_msg*>(getStatusResponse7.data());
4557 rc = decode_get_status_resp(
4558 responseMsg7, getStatusResponse7.size() - hdrSize, &completionCode,
4559 &currentState, &previousState, &auxState, &auxStateStatus,
4560 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4561 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4562
4563 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4564 getStatusResponse8{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004565 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304566 auto responseMsg8 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304567 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304568 reinterpret_cast<const pldm_msg*>(getStatusResponse8.data());
4569 rc = decode_get_status_resp(
4570 responseMsg8, getStatusResponse8.size() - hdrSize, &completionCode,
4571 &currentState, &previousState, &auxState, &auxStateStatus,
4572 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4573 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4574
4575 // AuxState is not PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER when the state is
4576 // IDLE
4577 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_get_status_resp)>
4578 getStatusResponse9{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
4579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4580 auto responseMsg9 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304581 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304582 reinterpret_cast<const pldm_msg*>(getStatusResponse9.data());
4583 rc = decode_get_status_resp(
4584 responseMsg9, getStatusResponse9.size() - hdrSize, &completionCode,
4585 &currentState, &previousState, &auxState, &auxStateStatus,
4586 &progressPercent, &reasonCode, &updateOptionFlagsEnabled);
4587 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4588}
4589
4590TEST(CancelUpdateComponent, goodPathEncodeRequest)
4591{
4592 constexpr uint8_t instanceId = 9;
4593 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304594 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304595 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4596
4597 auto rc = encode_cancel_update_component_req(
4598 instanceId, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4599 EXPECT_EQ(rc, PLDM_SUCCESS);
4600
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004601 constexpr std::array<uint8_t, hdrSize> outRequest{0x89, 0x05, 0x1c};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304602 EXPECT_EQ(request, outRequest);
4603}
4604
4605TEST(CancelUpdateComponent, errorPathEncodeRequest)
4606{
4607 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304608 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304609 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4610
4611 auto rc = encode_cancel_update_component_req(
4612 0, nullptr, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES);
4613 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4614
4615 rc = encode_cancel_update_component_req(
4616 0, requestMsg, PLDM_CANCEL_UPDATE_COMPONENT_REQ_BYTES + 1);
4617 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4618}
4619
4620TEST(CancelUpdateComponent, testGoodDecodeResponse)
4621{
4622 uint8_t completionCode = 0;
4623 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4624 cancelUpdateComponentResponse1{0x00, 0x00, 0x00, 0x00};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304625 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304626 auto responseMsg1 = reinterpret_cast<const pldm_msg*>(
4627 cancelUpdateComponentResponse1.data());
4628 auto rc = decode_cancel_update_component_resp(
4629 responseMsg1, cancelUpdateComponentResponse1.size() - hdrSize,
4630 &completionCode);
4631 EXPECT_EQ(rc, PLDM_SUCCESS);
4632 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4633
4634 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4635 cancelUpdateComponentResponse2{0x00, 0x00, 0x00, 0x86};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304636 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304637 auto responseMsg2 = reinterpret_cast<const pldm_msg*>(
4638 cancelUpdateComponentResponse2.data());
4639 rc = decode_cancel_update_component_resp(
4640 responseMsg2, cancelUpdateComponentResponse2.size() - hdrSize,
4641 &completionCode);
4642 EXPECT_EQ(rc, PLDM_SUCCESS);
4643 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4644}
4645
4646TEST(CancelUpdateComponent, testBadDecodeResponse)
4647{
4648 uint8_t completionCode = 0;
4649 constexpr std::array<uint8_t, hdrSize> cancelUpdateComponentResponse{
4650 0x00, 0x00, 0x00};
4651 auto responseMsg =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304652 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304653 reinterpret_cast<const pldm_msg*>(cancelUpdateComponentResponse.data());
4654
4655 auto rc = decode_cancel_update_component_resp(
4656 nullptr, cancelUpdateComponentResponse.size() - hdrSize,
4657 &completionCode);
4658 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4659
4660 rc = decode_cancel_update_component_resp(
4661 responseMsg, cancelUpdateComponentResponse.size() - hdrSize, nullptr);
4662 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4663
4664 rc = decode_cancel_update_component_resp(
4665 responseMsg, cancelUpdateComponentResponse.size() - hdrSize,
4666 &completionCode);
4667 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4668}
4669
4670TEST(CancelUpdate, goodPathEncodeRequest)
4671{
4672 constexpr uint8_t instanceId = 10;
4673 std::array<uint8_t, hdrSize> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304674 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304675 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4676
4677 auto rc = encode_cancel_update_req(instanceId, requestMsg,
4678 PLDM_CANCEL_UPDATE_REQ_BYTES);
4679 EXPECT_EQ(rc, PLDM_SUCCESS);
4680
Pavithra Barithayadc7d3b52024-02-06 23:46:49 -06004681 constexpr std::array<uint8_t, hdrSize> outRequest{0x8a, 0x05, 0x1d};
Andrew Jeffery9c766792022-08-10 23:12:49 +09304682 EXPECT_EQ(request, outRequest);
4683}
4684
4685TEST(CancelUpdate, errorPathEncodeRequest)
4686{
4687 std::array<uint8_t, hdrSize + sizeof(uint8_t)> request{};
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304688 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304689 auto requestMsg = reinterpret_cast<pldm_msg*>(request.data());
4690
4691 auto rc =
4692 encode_cancel_update_req(0, nullptr, PLDM_CANCEL_UPDATE_REQ_BYTES);
4693 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4694
4695 rc = encode_cancel_update_req(0, requestMsg,
4696 PLDM_CANCEL_UPDATE_REQ_BYTES + 1);
4697 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4698}
4699
4700TEST(CancelUpdate, goodPathDecodeResponse)
4701{
4702 constexpr std::bitset<64> nonFunctioningComponentBitmap1{0};
4703 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4704 cancelUpdateResponse1{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4706 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304707 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304708 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4709 uint8_t completionCode = 0;
4710 bool8_t nonFunctioningComponentIndication = 0;
4711 bitfield64_t nonFunctioningComponentBitmap{0};
4712 auto rc = decode_cancel_update_resp(
4713 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4714 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4715 EXPECT_EQ(rc, PLDM_SUCCESS);
4716 EXPECT_EQ(completionCode, PLDM_SUCCESS);
4717 EXPECT_EQ(nonFunctioningComponentIndication,
4718 PLDM_FWUP_COMPONENTS_FUNCTIONING);
4719 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4720 nonFunctioningComponentBitmap1);
4721
4722 constexpr std::bitset<64> nonFunctioningComponentBitmap2{0x0101};
4723 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4724 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
4725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4726 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304727 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304728 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4729 rc = decode_cancel_update_resp(
4730 responseMsg2, cancelUpdateResponse2.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_NOT_FUNCTIONING);
4736 EXPECT_EQ(nonFunctioningComponentBitmap.value,
4737 nonFunctioningComponentBitmap2);
4738
4739 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4740 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x86};
4741 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304742 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304743 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4744 rc = decode_cancel_update_resp(
4745 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4746 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4747 EXPECT_EQ(rc, PLDM_SUCCESS);
4748 EXPECT_EQ(completionCode, PLDM_FWUP_BUSY_IN_BACKGROUND);
4749}
4750
4751TEST(CancelUpdate, errorPathDecodeResponse)
4752{
4753 constexpr std::array<uint8_t, hdrSize> cancelUpdateResponse1{0x00, 0x00,
4754 0x00};
4755 auto responseMsg1 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304756 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304757 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse1.data());
4758 uint8_t completionCode = 0;
4759 bool8_t nonFunctioningComponentIndication = 0;
4760 bitfield64_t nonFunctioningComponentBitmap{0};
4761
4762 auto rc = decode_cancel_update_resp(
4763 nullptr, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4764 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4765 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4766
4767 rc = decode_cancel_update_resp(
4768 responseMsg1, cancelUpdateResponse1.size() - hdrSize, nullptr,
4769 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4770 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4771
4772 rc = decode_cancel_update_resp(
4773 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4774 nullptr, &nonFunctioningComponentBitmap);
4775 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4776
4777 rc = decode_cancel_update_resp(
4778 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4779 &nonFunctioningComponentIndication, nullptr);
4780 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4781
4782 rc = decode_cancel_update_resp(
4783 responseMsg1, cancelUpdateResponse1.size() - hdrSize, &completionCode,
4784 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4785 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4786
4787 constexpr std::array<uint8_t, hdrSize + sizeof(completionCode)>
4788 cancelUpdateResponse2{0x00, 0x00, 0x00, 0x00};
4789 auto responseMsg2 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304790 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304791 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse2.data());
4792 rc = decode_cancel_update_resp(
4793 responseMsg2, cancelUpdateResponse2.size() - hdrSize, &completionCode,
4794 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4795 EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
4796
4797 constexpr std::array<uint8_t, hdrSize + sizeof(pldm_cancel_update_resp)>
4798 cancelUpdateResponse3{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
4799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
4800 auto responseMsg3 =
Andrew Jefferyd0ba43a2024-09-09 15:50:17 +09304801 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
Andrew Jeffery9c766792022-08-10 23:12:49 +09304802 reinterpret_cast<const pldm_msg*>(cancelUpdateResponse3.data());
4803 rc = decode_cancel_update_resp(
4804 responseMsg3, cancelUpdateResponse3.size() - hdrSize, &completionCode,
4805 &nonFunctioningComponentIndication, &nonFunctioningComponentBitmap);
4806 EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
4807}