1 #include "inventory_manager.hpp"
2
3 #include "common/utils.hpp"
4 #include "xyz/openbmc_project/Software/Version/server.hpp"
5
6 #include <libpldm/firmware_update.h>
7
8 #include <phosphor-logging/lg2.hpp>
9
10 #include <functional>
11
12 PHOSPHOR_LOG2_USING;
13
14 namespace pldm
15 {
16 namespace fw_update
17 {
discoverFDs(const std::vector<mctp_eid_t> & eids)18 void InventoryManager::discoverFDs(const std::vector<mctp_eid_t>& eids)
19 {
20 for (const auto& eid : eids)
21 {
22 try
23 {
24 sendQueryDeviceIdentifiersRequest(eid);
25 }
26 catch (const std::exception& e)
27 {
28 error(
29 "Failed to discover file descriptors for endpoint ID {EID} with {Error}",
30 "EID", eid, "ERROR", e);
31 }
32 }
33 }
34
sendQueryDeviceIdentifiersRequest(mctp_eid_t eid)35 void InventoryManager::sendQueryDeviceIdentifiersRequest(mctp_eid_t eid)
36 {
37 auto instanceId = instanceIdDb.next(eid);
38 Request requestMsg(
39 sizeof(pldm_msg_hdr) + PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES);
40 auto request = new (requestMsg.data()) pldm_msg;
41 auto rc = encode_query_device_identifiers_req(
42 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, request);
43 if (rc)
44 {
45 instanceIdDb.free(eid, instanceId);
46 error(
47 "Failed to encode query device identifiers request for endpoint ID {EID} with response code {RC}",
48 "EID", eid, "RC", rc);
49 throw std::runtime_error(
50 "Failed to encode QueryDeviceIdentifiers request");
51 }
52
53 rc = handler.registerRequest(
54 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DEVICE_IDENTIFIERS,
55 std::move(requestMsg),
56 std::bind_front(&InventoryManager::queryDeviceIdentifiers, this));
57 if (rc)
58 {
59 error(
60 "Failed to send query device identifiers request for endpoint ID {EID} with response code {RC}",
61 "EID", eid, "RC", rc);
62 throw std::runtime_error(
63 "Failed to send QueryDeviceIdentifiers request");
64 }
65 }
66
queryDeviceIdentifiers(mctp_eid_t eid,const pldm_msg * response,size_t respMsgLen)67 void InventoryManager::queryDeviceIdentifiers(
68 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
69 {
70 if (response == nullptr || !respMsgLen)
71 {
72 error(
73 "No response received for query device identifiers for endpoint ID {EID}",
74 "EID", eid);
75 return;
76 }
77
78 uint8_t completionCode = PLDM_SUCCESS;
79 uint32_t deviceIdentifiersLen = 0;
80 uint8_t descriptorCount = 0;
81 uint8_t* descriptorPtr = nullptr;
82
83 auto rc = decode_query_device_identifiers_resp(
84 response, respMsgLen, &completionCode, &deviceIdentifiersLen,
85 &descriptorCount, &descriptorPtr);
86 if (rc)
87 {
88 error(
89 "Failed to decode query device identifiers response for endpoint ID {EID} and descriptor count {DESCRIPTOR_COUNT}, response code {RC}",
90 "EID", eid, "DESCRIPTOR_COUNT", descriptorCount, "RC", rc);
91 return;
92 }
93
94 if (completionCode)
95 {
96 error(
97 "Failed to query device identifiers response for endpoint ID {EID}, completion code {CC}",
98 "EID", eid, "CC", completionCode);
99 return;
100 }
101
102 Descriptors descriptors{};
103 while (descriptorCount-- && (deviceIdentifiersLen > 0))
104 {
105 uint16_t descriptorType = 0;
106 variable_field descriptorData{};
107
108 rc = decode_descriptor_type_length_value(
109 descriptorPtr, deviceIdentifiersLen, &descriptorType,
110 &descriptorData);
111 if (rc)
112 {
113 error(
114 "Failed to decode descriptor type {TYPE}, length {LENGTH} and value for endpoint ID {EID}, response code {RC}",
115 "TYPE", descriptorType, "LENGTH", deviceIdentifiersLen, "EID",
116 eid, "RC", rc);
117 return;
118 }
119
120 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
121 {
122 std::vector<uint8_t> descData(
123 descriptorData.ptr, descriptorData.ptr + descriptorData.length);
124 descriptors.emplace(descriptorType, std::move(descData));
125 }
126 else
127 {
128 uint8_t descriptorTitleStrType = 0;
129 variable_field descriptorTitleStr{};
130 variable_field vendorDefinedDescriptorData{};
131
132 rc = decode_vendor_defined_descriptor_value(
133 descriptorData.ptr, descriptorData.length,
134 &descriptorTitleStrType, &descriptorTitleStr,
135 &vendorDefinedDescriptorData);
136 if (rc)
137 {
138 error(
139 "Failed to decode vendor-defined descriptor value for endpoint ID {EID}, response code {RC}",
140 "EID", eid, "RC", rc);
141 return;
142 }
143
144 auto vendorDefinedDescriptorTitleStr =
145 utils::toString(descriptorTitleStr);
146 std::vector<uint8_t> vendorDescData(
147 vendorDefinedDescriptorData.ptr,
148 vendorDefinedDescriptorData.ptr +
149 vendorDefinedDescriptorData.length);
150 descriptors.emplace(descriptorType,
151 std::make_tuple(vendorDefinedDescriptorTitleStr,
152 vendorDescData));
153 }
154 auto nextDescriptorOffset =
155 sizeof(pldm_descriptor_tlv().descriptor_type) +
156 sizeof(pldm_descriptor_tlv().descriptor_length) +
157 descriptorData.length;
158 descriptorPtr += nextDescriptorOffset;
159 deviceIdentifiersLen -= nextDescriptorOffset;
160 }
161
162 descriptorMap.emplace(eid, std::move(descriptors));
163
164 // Send GetFirmwareParameters request
165 sendGetFirmwareParametersRequest(eid);
166 }
167
sendQueryDownstreamDevicesRequest(mctp_eid_t eid)168 void InventoryManager::sendQueryDownstreamDevicesRequest(mctp_eid_t eid)
169 {
170 Request requestMsg(sizeof(pldm_msg_hdr));
171 auto instanceId = instanceIdDb.next(eid);
172 auto request = new (requestMsg.data()) pldm_msg;
173 auto rc = encode_query_downstream_devices_req(instanceId, request);
174 if (rc)
175 {
176 instanceIdDb.free(eid, instanceId);
177 error(
178 "Failed to encode query downstream devices request for endpoint ID EID {EID} with response code {RC}",
179 "EID", eid, "RC", rc);
180 throw std::runtime_error(
181 "Failed to encode query downstream devices request");
182 }
183
184 rc = handler.registerRequest(
185 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DOWNSTREAM_DEVICES,
186 std::move(requestMsg),
187 std::bind_front(&InventoryManager::queryDownstreamDevices, this));
188 if (rc)
189 {
190 error(
191 "Failed to send QueryDownstreamDevices request for endpoint ID {EID} with response code {RC}",
192 "EID", eid, "RC", rc);
193 }
194 }
195
queryDownstreamDevices(mctp_eid_t eid,const pldm_msg * response,size_t respMsgLen)196 void InventoryManager::queryDownstreamDevices(
197 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
198 {
199 if (!response || !respMsgLen)
200 {
201 error(
202 "No response received for QueryDownstreamDevices for endpoint ID {EID}",
203 "EID", eid);
204 return;
205 }
206
207 pldm_query_downstream_devices_resp downstreamDevicesResp{};
208 auto rc = decode_query_downstream_devices_resp(response, respMsgLen,
209 &downstreamDevicesResp);
210 if (rc)
211 {
212 error(
213 "Decoding QueryDownstreamDevices response failed for endpoint ID {EID} with response code {RC}",
214 "EID", eid, "RC", rc);
215 return;
216 }
217
218 switch (downstreamDevicesResp.completion_code)
219 {
220 case PLDM_SUCCESS:
221 break;
222 case PLDM_ERROR_UNSUPPORTED_PLDM_CMD:
223 /* QueryDownstreamDevices is optional, consider the device does not
224 * support Downstream Devices.
225 */
226 info("Endpoint ID {EID} does not support QueryDownstreamDevices",
227 "EID", eid);
228 return;
229 default:
230 error(
231 "QueryDownstreamDevices response failed with error completion code for endpoint ID {EID} with completion code {CC}",
232 "EID", eid, "CC", downstreamDevicesResp.completion_code);
233 return;
234 }
235
236 switch (downstreamDevicesResp.downstream_device_update_supported)
237 {
238 case PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED:
239 /** DataTransferHandle will be skipped when TransferOperationFlag is
240 * `GetFirstPart`. Use 0x0 as default by following example in
241 * Figure 9 in DSP0267 1.1.0
242 */
243 try
244 {
245 sendQueryDownstreamIdentifiersRequest(eid, 0x0,
246 PLDM_GET_FIRSTPART);
247 }
248 catch (const std::exception& e)
249 {
250 error(
251 "Failed to send QueryDownstreamIdentifiers request for endpoint ID {EID} with {ERROR}",
252 "EID", eid, "ERROR", e);
253 }
254 break;
255 case PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_NOT_SUPPORTED:
256 /* The FDP does not support firmware updates but may report
257 * inventory information on downstream devices.
258 * In this scenario, sends only GetDownstreamFirmwareParameters
259 * to the FDP.
260 * The definition can be found at Table 15 of DSP0267_1.1.0
261 */
262 break;
263 default:
264 error(
265 "Unknown response of DownstreamDeviceUpdateSupported from endpoint ID {EID} with value {VALUE}",
266 "EID", eid, "VALUE",
267 downstreamDevicesResp.downstream_device_update_supported);
268 return;
269 }
270 }
271
sendQueryDownstreamIdentifiersRequest(mctp_eid_t eid,uint32_t dataTransferHandle,enum transfer_op_flag transferOperationFlag)272 void InventoryManager::sendQueryDownstreamIdentifiersRequest(
273 mctp_eid_t eid, uint32_t dataTransferHandle,
274 enum transfer_op_flag transferOperationFlag)
275 {
276 auto instanceId = instanceIdDb.next(eid);
277 Request requestMsg(
278 sizeof(pldm_msg_hdr) + PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES);
279 auto request = new (requestMsg.data()) pldm_msg;
280 pldm_query_downstream_identifiers_req requestParameters{
281 dataTransferHandle, static_cast<uint8_t>(transferOperationFlag)};
282
283 auto rc = encode_query_downstream_identifiers_req(
284 instanceId, &requestParameters, request,
285 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES);
286 if (rc)
287 {
288 instanceIdDb.free(eid, instanceId);
289 error(
290 "Failed to encode query downstream identifiers request for endpoint ID {EID} with response code {RC}",
291 "EID", eid, "RC", rc);
292 throw std::runtime_error(
293 "Failed to encode query downstream identifiers request");
294 }
295
296 rc = handler.registerRequest(
297 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS,
298 std::move(requestMsg),
299 std::bind_front(&InventoryManager::queryDownstreamIdentifiers, this));
300 if (rc)
301 {
302 error(
303 "Failed to send QueryDownstreamIdentifiers request for endpoint ID {EID} with response code {RC}",
304 "EID", eid, "RC", rc);
305 }
306 }
307
queryDownstreamIdentifiers(mctp_eid_t eid,const pldm_msg * response,size_t respMsgLen)308 void InventoryManager::queryDownstreamIdentifiers(
309 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
310 {
311 if (!response || !respMsgLen)
312 {
313 error(
314 "No response received for QueryDownstreamIdentifiers for endpoint ID {EID}",
315 "EID", eid);
316 descriptorMap.erase(eid);
317 return;
318 }
319
320 pldm_query_downstream_identifiers_resp downstreamIds{};
321 pldm_downstream_device_iter devs{};
322
323 auto rc = decode_query_downstream_identifiers_resp(response, respMsgLen,
324 &downstreamIds, &devs);
325 if (rc)
326 {
327 error(
328 "Decoding QueryDownstreamIdentifiers response failed for endpoint ID {EID} with response code {RC}",
329 "EID", eid, "RC", rc);
330 return;
331 }
332
333 if (downstreamIds.completion_code)
334 {
335 error(
336 "QueryDownstreamIdentifiers response failed with error completion code for endpoint ID {EID} with completion code {CC}",
337 "EID", eid, "CC", unsigned(downstreamIds.completion_code));
338 return;
339 }
340
341 DownstreamDeviceInfo initialDownstreamDevices{};
342 DownstreamDeviceInfo* downstreamDevices;
343 if (!downstreamDescriptorMap.contains(eid) ||
344 downstreamIds.transfer_flag == PLDM_START ||
345 downstreamIds.transfer_flag == PLDM_START_AND_END)
346 {
347 downstreamDevices = &initialDownstreamDevices;
348 }
349 else
350 {
351 downstreamDevices = &downstreamDescriptorMap.at(eid);
352 }
353
354 pldm_downstream_device dev;
355 foreach_pldm_downstream_device(devs, dev, rc)
356 {
357 pldm_descriptor desc;
358 Descriptors descriptors{};
359 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
360 {
361 const auto descriptorData =
362 new (const_cast<void*>(desc.descriptor_data))
363 uint8_t[desc.descriptor_length];
364 if (desc.descriptor_type != PLDM_FWUP_VENDOR_DEFINED)
365 {
366 std::vector<uint8_t> descData(
367 descriptorData, descriptorData + desc.descriptor_length);
368 descriptors.emplace(desc.descriptor_type, std::move(descData));
369 }
370 else
371 {
372 uint8_t descriptorTitleStrType = 0;
373 variable_field descriptorTitleStr{};
374 variable_field vendorDefinedDescriptorData{};
375
376 rc = decode_vendor_defined_descriptor_value(
377 descriptorData, desc.descriptor_length,
378 &descriptorTitleStrType, &descriptorTitleStr,
379 &vendorDefinedDescriptorData);
380
381 if (rc)
382 {
383 error(
384 "Decoding Vendor-defined descriptor value failed for endpoint ID {EID} with response code {RC}",
385 "EID", eid, "RC", rc);
386 return;
387 }
388
389 auto vendorDefinedDescriptorTitleStr =
390 utils::toString(descriptorTitleStr);
391 std::vector<uint8_t> vendorDescData(
392 vendorDefinedDescriptorData.ptr,
393 vendorDefinedDescriptorData.ptr +
394 vendorDefinedDescriptorData.length);
395 descriptors.emplace(
396 desc.descriptor_type,
397 std::make_tuple(vendorDefinedDescriptorTitleStr,
398 vendorDescData));
399 }
400 }
401 if (rc)
402 {
403 error(
404 "Failed to decode downstream device descriptor for endpoint ID {EID} with response code {RC}",
405 "EID", eid, "RC", rc);
406 return;
407 }
408 downstreamDevices->emplace(dev.downstream_device_index, descriptors);
409 }
410 if (rc)
411 {
412 error(
413 "Failed to decode downstream devices from iterator for endpoint ID {EID} with response code {RC}",
414 "EID", eid, "RC", rc);
415 return;
416 }
417
418 switch (downstreamIds.transfer_flag)
419 {
420 case PLDM_START:
421 downstreamDescriptorMap.insert_or_assign(
422 eid, std::move(initialDownstreamDevices));
423 [[fallthrough]];
424 case PLDM_MIDDLE:
425 sendQueryDownstreamIdentifiersRequest(
426 eid, downstreamIds.next_data_transfer_handle,
427 PLDM_GET_NEXTPART);
428 break;
429 case PLDM_START_AND_END:
430 downstreamDescriptorMap.insert_or_assign(
431 eid, std::move(initialDownstreamDevices));
432 /** DataTransferHandle will be skipped when TransferOperationFlag is
433 * `GetFirstPart`. Use 0x0 as default by following example in
434 * Figure 9 in DSP0267 1.1.0
435 */
436 [[fallthrough]];
437 case PLDM_END:
438 sendGetDownstreamFirmwareParametersRequest(eid, 0x0,
439 PLDM_GET_FIRSTPART);
440 break;
441 }
442 }
443
sendGetDownstreamFirmwareParametersRequest(mctp_eid_t eid,uint32_t dataTransferHandle,enum transfer_op_flag transferOperationFlag)444 void InventoryManager::sendGetDownstreamFirmwareParametersRequest(
445 mctp_eid_t eid, uint32_t dataTransferHandle,
446 enum transfer_op_flag transferOperationFlag)
447 {
448 Request requestMsg(sizeof(pldm_msg_hdr) +
449 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES);
450 auto instanceId = instanceIdDb.next(eid);
451 auto request = new (requestMsg.data()) pldm_msg;
452 pldm_get_downstream_firmware_parameters_req requestParameters{
453 dataTransferHandle, static_cast<uint8_t>(transferOperationFlag)};
454 auto rc = encode_get_downstream_firmware_parameters_req(
455 instanceId, &requestParameters, request,
456 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES);
457 if (rc)
458 {
459 instanceIdDb.free(eid, instanceId);
460 error(
461 "Failed to encode query downstream firmware parameters request for endpoint ID {EID} with response code {RC}",
462 "EID", eid, "RC", rc);
463 throw std::runtime_error(
464 "Failed to encode query downstream firmware parameters request");
465 }
466
467 rc = handler.registerRequest(
468 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DOWNSTREAM_FIRMWARE_PARAMETERS,
469 std::move(requestMsg),
470 std::bind_front(&InventoryManager::getDownstreamFirmwareParameters,
471 this));
472 if (rc)
473 {
474 error(
475 "Failed to send QueryDownstreamFirmwareParameters request for endpoint ID {EID} with response code {RC}",
476 "EID", eid, "RC", rc);
477 }
478 }
479
getDownstreamFirmwareParameters(mctp_eid_t eid,const pldm_msg * response,size_t respMsgLen)480 void InventoryManager::getDownstreamFirmwareParameters(
481 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
482 {
483 if (!response || !respMsgLen)
484 {
485 error(
486 "No response received for QueryDownstreamFirmwareParameters for endpoint ID {EID}",
487 "EID", eid);
488 descriptorMap.erase(eid);
489 return;
490 }
491
492 pldm_get_downstream_firmware_parameters_resp resp{};
493 pldm_downstream_device_parameters_iter params{};
494 pldm_downstream_device_parameters_entry entry{};
495
496 auto rc = decode_get_downstream_firmware_parameters_resp(
497 response, respMsgLen, &resp, ¶ms);
498
499 if (rc)
500 {
501 error(
502 "Decoding QueryDownstreamFirmwareParameters response failed for endpoint ID {EID} with response code {RC}",
503 "EID", eid, "RC", rc);
504 return;
505 }
506
507 if (resp.completion_code)
508 {
509 error(
510 "QueryDownstreamFirmwareParameters response failed with error completion code for endpoint ID {EID} with completion code {CC}",
511 "EID", eid, "CC", resp.completion_code);
512 return;
513 }
514
515 foreach_pldm_downstream_device_parameters_entry(params, entry, rc)
516 {
517 // Reserved for upcoming use
518 [[maybe_unused]] variable_field activeCompVerStr{
519 reinterpret_cast<const uint8_t*>(entry.active_comp_ver_str),
520 entry.active_comp_ver_str_len};
521 }
522 if (rc)
523 {
524 error(
525 "Failed to decode downstream device parameters from iterator for endpoint ID {EID} with response code {RC}",
526 "EID", eid, "RC", rc);
527 return;
528 }
529
530 switch (resp.transfer_flag)
531 {
532 case PLDM_START:
533 case PLDM_MIDDLE:
534 sendGetDownstreamFirmwareParametersRequest(
535 eid, resp.next_data_transfer_handle, PLDM_GET_NEXTPART);
536 break;
537 }
538 }
539
sendGetFirmwareParametersRequest(mctp_eid_t eid)540 void InventoryManager::sendGetFirmwareParametersRequest(mctp_eid_t eid)
541 {
542 auto instanceId = instanceIdDb.next(eid);
543 Request requestMsg(
544 sizeof(pldm_msg_hdr) + PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES);
545 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
546 auto rc = encode_get_firmware_parameters_req(
547 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, request);
548 if (rc)
549 {
550 instanceIdDb.free(eid, instanceId);
551 error(
552 "Failed to encode get firmware parameters req for endpoint ID {EID}, response code {RC}",
553 "EID", eid, "RC", rc);
554 return;
555 }
556
557 rc = handler.registerRequest(
558 eid, instanceId, PLDM_FWUP, PLDM_GET_FIRMWARE_PARAMETERS,
559 std::move(requestMsg),
560 std::bind_front(&InventoryManager::getFirmwareParameters, this));
561 if (rc)
562 {
563 error(
564 "Failed to send get firmware parameters request for endpoint ID {EID}, response code {RC}",
565 "EID", eid, "RC", rc);
566 }
567 }
568
getFirmwareParameters(mctp_eid_t eid,const pldm_msg * response,size_t respMsgLen)569 void InventoryManager::getFirmwareParameters(
570 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
571 {
572 if (response == nullptr || !respMsgLen)
573 {
574 error(
575 "No response received for get firmware parameters for endpoint ID {EID}",
576 "EID", eid);
577 descriptorMap.erase(eid);
578 return;
579 }
580
581 pldm_get_firmware_parameters_resp fwParams{};
582 variable_field activeCompImageSetVerStr{};
583 variable_field pendingCompImageSetVerStr{};
584 variable_field compParamTable{};
585
586 auto rc = decode_get_firmware_parameters_resp(
587 response, respMsgLen, &fwParams, &activeCompImageSetVerStr,
588 &pendingCompImageSetVerStr, &compParamTable);
589 if (rc)
590 {
591 error(
592 "Failed to decode get firmware parameters response for endpoint ID {EID}, response code {RC}",
593 "EID", eid, "RC", rc);
594 return;
595 }
596
597 if (fwParams.completion_code)
598 {
599 auto fw_param_cc = fwParams.completion_code;
600 error(
601 "Failed to get firmware parameters response for endpoint ID {EID}, completion code {CC}",
602 "EID", eid, "CC", fw_param_cc);
603 return;
604 }
605
606 auto compParamPtr = compParamTable.ptr;
607 auto compParamTableLen = compParamTable.length;
608 pldm_component_parameter_entry compEntry{};
609 variable_field activeCompVerStr{};
610 variable_field pendingCompVerStr{};
611
612 ComponentInfo componentInfo{};
613 while (fwParams.comp_count-- && (compParamTableLen > 0))
614 {
615 auto rc = decode_get_firmware_parameters_resp_comp_entry(
616 compParamPtr, compParamTableLen, &compEntry, &activeCompVerStr,
617 &pendingCompVerStr);
618 if (rc)
619 {
620 error(
621 "Failed to decode component parameter table entry for endpoint ID {EID}, response code {RC}",
622 "EID", eid, "RC", rc);
623 return;
624 }
625
626 auto compClassification = compEntry.comp_classification;
627 auto compIdentifier = compEntry.comp_identifier;
628 componentInfo.emplace(
629 std::make_pair(compClassification, compIdentifier),
630 compEntry.comp_classification_index);
631 compParamPtr += sizeof(pldm_component_parameter_entry) +
632 activeCompVerStr.length + pendingCompVerStr.length;
633 compParamTableLen -= sizeof(pldm_component_parameter_entry) +
634 activeCompVerStr.length + pendingCompVerStr.length;
635 }
636 componentInfoMap.emplace(eid, std::move(componentInfo));
637 }
638
639 } // namespace fw_update
640
641 } // namespace pldm
642