xref: /openbmc/pldm/fw-update/inventory_manager.cpp (revision 8b169dc51d7dfe8512add038169c0644f424b4d9)
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, &params);
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