xref: /openbmc/libpldm/bindings/cpp/types.cpp (revision d6a957481638b00a49aed15d04b60d3d32fede54)
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