1 #include <bitset>
2 #include <cstdint>
3 #include <libpldm/firmware_update.h>
4 #include <libpldm++/types.hpp>
5 #include <libpldm++/firmware_update.hpp>
6 #include <map>
7 #include <string>
8 #include <vector>
9 #include <optional>
10 #include <memory>
11
DescriptorData(const struct DescriptorData & ref)12 pldm::fw_update::DescriptorData::DescriptorData(const struct DescriptorData &ref)
13 : vendorDefinedDescriptorTitle(ref.vendorDefinedDescriptorTitle),
14 data(ref.data)
15 {
16 }
17
DescriptorData(const std::vector<uint8_t> & data)18 pldm::fw_update::DescriptorData::DescriptorData(const std::vector<uint8_t> &data)
19 : data(data)
20 {
21 }
22
DescriptorData(const std::string & title,const std::vector<uint8_t> & data)23 pldm::fw_update::DescriptorData::DescriptorData(
24 const std::string &title, const std::vector<uint8_t> &data)
25 : vendorDefinedDescriptorTitle(title), data(data)
26 {
27 }
28
29 LIBPLDM_ABI_TESTING
~DescriptorData()30 pldm::fw_update::DescriptorData::~DescriptorData()
31 {
32 }
33
34 LIBPLDM_ABI_TESTING
operator ==(const DescriptorData & other) const35 bool pldm::fw_update::DescriptorData::operator==(
36 const DescriptorData &other) const
37 {
38 if (CompareNEQ(&DescriptorData::vendorDefinedDescriptorTitle, other)) {
39 return false;
40 }
41 if (CompareNEQ(&DescriptorData::data, other)) {
42 return false;
43 }
44 return true;
45 }
46
ComponentImageInfo(uint16_t componentClassification,uint16_t componentIdentifier,uint32_t componentComparisonStamp,std::bitset<16> componentOptions,std::bitset<16> requestedComponentActivationMethod,const variable_field & componentLocation,const std::string & componentVersion)47 pldm::fw_update::ComponentImageInfo::ComponentImageInfo(
48 uint16_t componentClassification, uint16_t componentIdentifier,
49 uint32_t componentComparisonStamp, std::bitset<16> componentOptions,
50 std::bitset<16> requestedComponentActivationMethod,
51 const variable_field &componentLocation,
52 const std::string &componentVersion)
53 : componentClassification(componentClassification),
54 componentIdentifier(componentIdentifier),
55 compComparisonStamp(componentComparisonStamp),
56 componentOptions(componentOptions),
57 requestedComponentActivationMethod(
58 requestedComponentActivationMethod),
59 componentLocation(componentLocation),
60 componentVersion(componentVersion)
61 {
62 }
63
64 LIBPLDM_ABI_TESTING
ComponentImageInfo(const ComponentImageInfo & ref)65 pldm::fw_update::ComponentImageInfo::ComponentImageInfo(
66 const ComponentImageInfo &ref)
67 : componentClassification(ref.componentClassification),
68 componentIdentifier(ref.componentIdentifier),
69 compComparisonStamp(ref.compComparisonStamp),
70 componentOptions(ref.componentOptions),
71 requestedComponentActivationMethod(
72 ref.requestedComponentActivationMethod),
73 componentLocation(ref.componentLocation),
74 componentVersion(ref.componentVersion)
75 {
76 }
77
78 LIBPLDM_ABI_TESTING
operator ==(const ComponentImageInfo & other) const79 bool pldm::fw_update::ComponentImageInfo::operator==(
80 const ComponentImageInfo &other) const
81 {
82 if (CompareNEQ(&ComponentImageInfo::componentClassification, other)) {
83 return false;
84 }
85 if (CompareNEQ(&ComponentImageInfo::componentIdentifier, other)) {
86 return false;
87 }
88 if (CompareNEQ(&ComponentImageInfo::compComparisonStamp, other)) {
89 return false;
90 }
91 if (CompareNEQ(&ComponentImageInfo::componentOptions, other)) {
92 return false;
93 }
94 if (CompareNEQ(&ComponentImageInfo::requestedComponentActivationMethod,
95 other)) {
96 return false;
97 }
98 if (HasMember(&ComponentImageInfo::componentLocation) &&
99 other.HasMember(&ComponentImageInfo::componentLocation)) {
100 if (componentLocation.length !=
101 other.componentLocation.length) {
102 return false;
103 }
104 }
105 if (CompareNEQ(&ComponentImageInfo::componentVersion, other)) {
106 return false;
107 }
108 return true;
109 }
110
111 LIBPLDM_ABI_TESTING
~ComponentImageInfo()112 pldm::fw_update::ComponentImageInfo::~ComponentImageInfo()
113 {
114 }
115
FirmwareDeviceIDRecord(const std::bitset<32> & deviceUpdateOptionFlags,const std::vector<size_t> & applicableComponents,const std::string & componentImageSetVersion,const std::map<uint16_t,std::unique_ptr<DescriptorData>> & descriptorsIn,const std::vector<uint8_t> & firmwareDevicePackageData)116 pldm::fw_update::FirmwareDeviceIDRecord::FirmwareDeviceIDRecord(
117 const std::bitset<32> &deviceUpdateOptionFlags,
118 const std::vector<size_t> &applicableComponents,
119 const std::string &componentImageSetVersion,
120 const std::map<uint16_t, std::unique_ptr<DescriptorData> >
121 &descriptorsIn,
122 const std::vector<uint8_t> &firmwareDevicePackageData)
123 : deviceUpdateOptionFlags(deviceUpdateOptionFlags),
124 applicableComponents(applicableComponents),
125 componentImageSetVersionString(componentImageSetVersion),
126 recordDescriptors([&descriptorsIn]() {
127 std::map<uint16_t, std::unique_ptr<DescriptorData> > res;
128 // We have to init the map here manually since the descriptor constructor
129 // is not a friend of the template which would otherwise be able to construct it.
130 for (const auto &[key, desc] : descriptorsIn) {
131 res[key] = std::unique_ptr<DescriptorData>(
132 new DescriptorData(*desc));
133 }
134
135 return res;
136 }()),
137 firmwareDevicePackageData(firmwareDevicePackageData)
138 {
139 }
140
141 LIBPLDM_ABI_TESTING
FirmwareDeviceIDRecord(const FirmwareDeviceIDRecord & ref)142 pldm::fw_update::FirmwareDeviceIDRecord::FirmwareDeviceIDRecord(
143 const FirmwareDeviceIDRecord &ref)
144 : deviceUpdateOptionFlags(ref.deviceUpdateOptionFlags),
145 applicableComponents(ref.applicableComponents),
146 componentImageSetVersionString(ref.componentImageSetVersionString),
147 recordDescriptors([&ref]() {
148 std::map<uint16_t, std::unique_ptr<DescriptorData> > res;
149 // We have to init the map here manually since the descriptor constructor
150 // is not a friend of the template which would otherwise be able to construct it.
151 for (const auto &[key, desc] : ref.recordDescriptors) {
152 res[key] = std::unique_ptr<DescriptorData>(
153 new DescriptorData(*desc));
154 }
155
156 return res;
157 }()),
158 firmwareDevicePackageData(ref.firmwareDevicePackageData)
159 {
160 }
161
162 LIBPLDM_ABI_TESTING
~FirmwareDeviceIDRecord()163 pldm::fw_update::FirmwareDeviceIDRecord::~FirmwareDeviceIDRecord()
164 {
165 }
166
167 LIBPLDM_ABI_TESTING
168 const std::vector<uint16_t>
getDescriptorTypes() const169 pldm::fw_update::FirmwareDeviceIDRecord::getDescriptorTypes() const
170 {
171 std::vector<uint16_t> res;
172 res.reserve(recordDescriptors.size());
173
174 for (auto &[k, _] : recordDescriptors) {
175 res.emplace_back(k);
176 }
177 return res;
178 }
179
180 LIBPLDM_ABI_TESTING
operator ==(const FirmwareDeviceIDRecord & other) const181 bool pldm::fw_update::FirmwareDeviceIDRecord::operator==(
182 const FirmwareDeviceIDRecord &other) const
183 {
184 if (CompareNEQ(&FirmwareDeviceIDRecord::deviceUpdateOptionFlags,
185 other)) {
186 return false;
187 }
188 if (CompareNEQ(&FirmwareDeviceIDRecord::applicableComponents, other)) {
189 return false;
190 }
191 if (CompareNEQ(&FirmwareDeviceIDRecord::componentImageSetVersionString,
192 other)) {
193 return false;
194 }
195 if (CompareNEQ(&FirmwareDeviceIDRecord::firmwareDevicePackageData,
196 other)) {
197 return false;
198 }
199
200 // need to manually compare the map since otherwise unique_ptr
201 // default comparison would only compare pointer values
202 if (HasMember(&FirmwareDeviceIDRecord::recordDescriptors) !=
203 other.HasMember(&FirmwareDeviceIDRecord::recordDescriptors)) {
204 // different size structs compare not equal
205 return false;
206 }
207 if (!HasMember(&FirmwareDeviceIDRecord::recordDescriptors) &&
208 !other.HasMember(&FirmwareDeviceIDRecord::recordDescriptors)) {
209 // none of them has record descriptors field
210 return true;
211 }
212
213 // both have record descriptors field
214 if (recordDescriptors.size() != other.recordDescriptors.size()) {
215 return false;
216 }
217
218 for (const auto &[k, v] : recordDescriptors) {
219 if (!other.recordDescriptors.contains(k)) {
220 return false;
221 }
222 const auto &otherDesc = other.recordDescriptors.at(k);
223
224 if (!v.get() && !otherDesc.get()) {
225 continue;
226 }
227 if (!v.get() || !otherDesc.get()) {
228 return false;
229 }
230
231 // descriptor value comparison
232 if (*v != *otherDesc) {
233 return false;
234 }
235 }
236
237 return true;
238 }
239
Package(const std::vector<FirmwareDeviceIDRecord> & firmwareDeviceIdRecords,const std::vector<ComponentImageInfo> & componentImageInformation)240 pldm::fw_update::Package::Package(
241 const std::vector<FirmwareDeviceIDRecord> &firmwareDeviceIdRecords,
242 const std::vector<ComponentImageInfo> &componentImageInformation)
243 : firmwareDeviceIdRecords(firmwareDeviceIdRecords),
244 componentImageInformation(componentImageInformation)
245 {
246 }
247
248 LIBPLDM_ABI_TESTING
Package(const Package & ref)249 pldm::fw_update::Package::Package(const Package &ref)
250 : firmwareDeviceIdRecords(ref.firmwareDeviceIdRecords),
251 componentImageInformation(ref.componentImageInformation)
252 {
253 }
254
255 LIBPLDM_ABI_TESTING
~Package()256 pldm::fw_update::Package::~Package()
257 {
258 }
259
260 LIBPLDM_ABI_TESTING
operator ==(const Package & other) const261 bool pldm::fw_update::Package::operator==(const Package &other) const
262 {
263 if (CompareNEQ(&Package::firmwareDeviceIdRecords, other)) {
264 return false;
265 }
266 if (CompareNEQ(&Package::componentImageInformation, other)) {
267 return false;
268 }
269 return true;
270 }
271