blob: 38e83923dced4a02647254d1bbb19e6d63ebd05b [file] [log] [blame]
Tom Joseph75356c12021-06-20 03:52:40 -07001#include "inventory_manager.hpp"
2
Tom Joseph75356c12021-06-20 03:52:40 -07003#include "common/utils.hpp"
4#include "xyz/openbmc_project/Software/Version/server.hpp"
5
George Liuc453e162022-12-21 17:16:23 +08006#include <libpldm/firmware_update.h>
7
Riya Dixit49cfb132023-03-02 04:26:53 -06008#include <phosphor-logging/lg2.hpp>
9
Tom Joseph75356c12021-06-20 03:52:40 -070010#include <functional>
11
Riya Dixit49cfb132023-03-02 04:26:53 -060012PHOSPHOR_LOG2_USING;
13
Tom Joseph75356c12021-06-20 03:52:40 -070014namespace pldm
15{
Tom Joseph75356c12021-06-20 03:52:40 -070016namespace fw_update
17{
Tom Joseph75356c12021-06-20 03:52:40 -070018void InventoryManager::discoverFDs(const std::vector<mctp_eid_t>& eids)
19{
20 for (const auto& eid : eids)
21 {
Unive Tien8b169dc2024-11-25 09:34:39 +080022 try
Tom Joseph75356c12021-06-20 03:52:40 -070023 {
Unive Tien8b169dc2024-11-25 09:34:39 +080024 sendQueryDeviceIdentifiersRequest(eid);
Tom Joseph75356c12021-06-20 03:52:40 -070025 }
Unive Tien8b169dc2024-11-25 09:34:39 +080026 catch (const std::exception& e)
27 {
28 error(
Unive Tien863b09b2025-02-07 16:51:37 +080029 "Failed to discover file descriptors for endpoint ID {EID} with {ERROR}",
Unive Tien8b169dc2024-11-25 09:34:39 +080030 "EID", eid, "ERROR", e);
31 }
32 }
33}
Tom Joseph75356c12021-06-20 03:52:40 -070034
Unive Tien8b169dc2024-11-25 09:34:39 +080035void 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),
Eric Yang70eca962025-05-11 01:48:15 +080056 [this](mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen) {
57 this->queryDeviceIdentifiers(eid, response, respMsgLen);
58 });
Unive Tien8b169dc2024-11-25 09:34:39 +080059 if (rc)
60 {
61 error(
62 "Failed to send query device identifiers request for endpoint ID {EID} with response code {RC}",
63 "EID", eid, "RC", rc);
64 throw std::runtime_error(
65 "Failed to send QueryDeviceIdentifiers request");
Tom Joseph75356c12021-06-20 03:52:40 -070066 }
67}
68
Patrick Williams16c2a0a2024-08-16 15:20:59 -040069void InventoryManager::queryDeviceIdentifiers(
70 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
Tom Joseph75356c12021-06-20 03:52:40 -070071{
72 if (response == nullptr || !respMsgLen)
73 {
Riya Dixit76f2c602024-03-28 07:34:12 -050074 error(
Unive Tien8b169dc2024-11-25 09:34:39 +080075 "No response received for query device identifiers for endpoint ID {EID}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050076 "EID", eid);
Tom Joseph75356c12021-06-20 03:52:40 -070077 return;
78 }
79
80 uint8_t completionCode = PLDM_SUCCESS;
81 uint32_t deviceIdentifiersLen = 0;
82 uint8_t descriptorCount = 0;
83 uint8_t* descriptorPtr = nullptr;
84
85 auto rc = decode_query_device_identifiers_resp(
86 response, respMsgLen, &completionCode, &deviceIdentifiersLen,
87 &descriptorCount, &descriptorPtr);
88 if (rc)
89 {
Riya Dixit49cfb132023-03-02 04:26:53 -060090 error(
Unive Tien8b169dc2024-11-25 09:34:39 +080091 "Failed to decode query device identifiers response for endpoint ID {EID} and descriptor count {DESCRIPTOR_COUNT}, response code {RC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -050092 "EID", eid, "DESCRIPTOR_COUNT", descriptorCount, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -070093 return;
94 }
95
96 if (completionCode)
97 {
Riya Dixit49cfb132023-03-02 04:26:53 -060098 error(
Unive Tien8b169dc2024-11-25 09:34:39 +080099 "Failed to query device identifiers response for endpoint ID {EID}, completion code {CC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500100 "EID", eid, "CC", completionCode);
Tom Joseph75356c12021-06-20 03:52:40 -0700101 return;
102 }
103
104 Descriptors descriptors{};
105 while (descriptorCount-- && (deviceIdentifiersLen > 0))
106 {
107 uint16_t descriptorType = 0;
108 variable_field descriptorData{};
109
110 rc = decode_descriptor_type_length_value(
111 descriptorPtr, deviceIdentifiersLen, &descriptorType,
112 &descriptorData);
113 if (rc)
114 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600115 error(
Unive Tien8b169dc2024-11-25 09:34:39 +0800116 "Failed to decode descriptor type {TYPE}, length {LENGTH} and value for endpoint ID {EID}, response code {RC}",
Riya Dixit76f2c602024-03-28 07:34:12 -0500117 "TYPE", descriptorType, "LENGTH", deviceIdentifiersLen, "EID",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500118 eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700119 return;
120 }
121
122 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
123 {
124 std::vector<uint8_t> descData(
125 descriptorData.ptr, descriptorData.ptr + descriptorData.length);
126 descriptors.emplace(descriptorType, std::move(descData));
127 }
128 else
129 {
130 uint8_t descriptorTitleStrType = 0;
131 variable_field descriptorTitleStr{};
132 variable_field vendorDefinedDescriptorData{};
133
134 rc = decode_vendor_defined_descriptor_value(
135 descriptorData.ptr, descriptorData.length,
136 &descriptorTitleStrType, &descriptorTitleStr,
137 &vendorDefinedDescriptorData);
138 if (rc)
139 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600140 error(
Unive Tien8b169dc2024-11-25 09:34:39 +0800141 "Failed to decode vendor-defined descriptor value for endpoint ID {EID}, response code {RC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500142 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700143 return;
144 }
145
146 auto vendorDefinedDescriptorTitleStr =
147 utils::toString(descriptorTitleStr);
148 std::vector<uint8_t> vendorDescData(
149 vendorDefinedDescriptorData.ptr,
150 vendorDefinedDescriptorData.ptr +
151 vendorDefinedDescriptorData.length);
152 descriptors.emplace(descriptorType,
153 std::make_tuple(vendorDefinedDescriptorTitleStr,
154 vendorDescData));
155 }
156 auto nextDescriptorOffset =
157 sizeof(pldm_descriptor_tlv().descriptor_type) +
158 sizeof(pldm_descriptor_tlv().descriptor_length) +
159 descriptorData.length;
160 descriptorPtr += nextDescriptorOffset;
161 deviceIdentifiersLen -= nextDescriptorOffset;
162 }
163
164 descriptorMap.emplace(eid, std::move(descriptors));
165
166 // Send GetFirmwareParameters request
167 sendGetFirmwareParametersRequest(eid);
168}
169
Unive Tien8b169dc2024-11-25 09:34:39 +0800170void InventoryManager::sendQueryDownstreamDevicesRequest(mctp_eid_t eid)
171{
172 Request requestMsg(sizeof(pldm_msg_hdr));
173 auto instanceId = instanceIdDb.next(eid);
174 auto request = new (requestMsg.data()) pldm_msg;
175 auto rc = encode_query_downstream_devices_req(instanceId, request);
176 if (rc)
177 {
178 instanceIdDb.free(eid, instanceId);
179 error(
180 "Failed to encode query downstream devices request for endpoint ID EID {EID} with response code {RC}",
181 "EID", eid, "RC", rc);
182 throw std::runtime_error(
183 "Failed to encode query downstream devices request");
184 }
185
186 rc = handler.registerRequest(
187 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DOWNSTREAM_DEVICES,
188 std::move(requestMsg),
Eric Yang70eca962025-05-11 01:48:15 +0800189 [this](mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen) {
190 this->queryDownstreamDevices(eid, response, respMsgLen);
191 });
Unive Tien8b169dc2024-11-25 09:34:39 +0800192 if (rc)
193 {
194 error(
195 "Failed to send QueryDownstreamDevices request for endpoint ID {EID} with response code {RC}",
196 "EID", eid, "RC", rc);
197 }
198}
199
200void InventoryManager::queryDownstreamDevices(
201 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
202{
203 if (!response || !respMsgLen)
204 {
205 error(
206 "No response received for QueryDownstreamDevices for endpoint ID {EID}",
207 "EID", eid);
208 return;
209 }
210
211 pldm_query_downstream_devices_resp downstreamDevicesResp{};
212 auto rc = decode_query_downstream_devices_resp(response, respMsgLen,
213 &downstreamDevicesResp);
214 if (rc)
215 {
216 error(
217 "Decoding QueryDownstreamDevices response failed for endpoint ID {EID} with response code {RC}",
218 "EID", eid, "RC", rc);
219 return;
220 }
221
222 switch (downstreamDevicesResp.completion_code)
223 {
224 case PLDM_SUCCESS:
225 break;
226 case PLDM_ERROR_UNSUPPORTED_PLDM_CMD:
227 /* QueryDownstreamDevices is optional, consider the device does not
228 * support Downstream Devices.
229 */
230 info("Endpoint ID {EID} does not support QueryDownstreamDevices",
231 "EID", eid);
232 return;
233 default:
234 error(
235 "QueryDownstreamDevices response failed with error completion code for endpoint ID {EID} with completion code {CC}",
236 "EID", eid, "CC", downstreamDevicesResp.completion_code);
237 return;
238 }
239
240 switch (downstreamDevicesResp.downstream_device_update_supported)
241 {
242 case PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_SUPPORTED:
243 /** DataTransferHandle will be skipped when TransferOperationFlag is
244 * `GetFirstPart`. Use 0x0 as default by following example in
245 * Figure 9 in DSP0267 1.1.0
246 */
247 try
248 {
249 sendQueryDownstreamIdentifiersRequest(eid, 0x0,
250 PLDM_GET_FIRSTPART);
251 }
252 catch (const std::exception& e)
253 {
254 error(
255 "Failed to send QueryDownstreamIdentifiers request for endpoint ID {EID} with {ERROR}",
256 "EID", eid, "ERROR", e);
257 }
258 break;
259 case PLDM_FWUP_DOWNSTREAM_DEVICE_UPDATE_NOT_SUPPORTED:
260 /* The FDP does not support firmware updates but may report
261 * inventory information on downstream devices.
262 * In this scenario, sends only GetDownstreamFirmwareParameters
263 * to the FDP.
264 * The definition can be found at Table 15 of DSP0267_1.1.0
265 */
266 break;
267 default:
268 error(
269 "Unknown response of DownstreamDeviceUpdateSupported from endpoint ID {EID} with value {VALUE}",
270 "EID", eid, "VALUE",
271 downstreamDevicesResp.downstream_device_update_supported);
272 return;
273 }
274}
275
276void InventoryManager::sendQueryDownstreamIdentifiersRequest(
277 mctp_eid_t eid, uint32_t dataTransferHandle,
278 enum transfer_op_flag transferOperationFlag)
279{
280 auto instanceId = instanceIdDb.next(eid);
281 Request requestMsg(
282 sizeof(pldm_msg_hdr) + PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES);
283 auto request = new (requestMsg.data()) pldm_msg;
284 pldm_query_downstream_identifiers_req requestParameters{
285 dataTransferHandle, static_cast<uint8_t>(transferOperationFlag)};
286
287 auto rc = encode_query_downstream_identifiers_req(
288 instanceId, &requestParameters, request,
289 PLDM_QUERY_DOWNSTREAM_IDENTIFIERS_REQ_BYTES);
290 if (rc)
291 {
292 instanceIdDb.free(eid, instanceId);
293 error(
294 "Failed to encode query downstream identifiers request for endpoint ID {EID} with response code {RC}",
295 "EID", eid, "RC", rc);
296 throw std::runtime_error(
297 "Failed to encode query downstream identifiers request");
298 }
299
300 rc = handler.registerRequest(
301 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DOWNSTREAM_IDENTIFIERS,
302 std::move(requestMsg),
Eric Yang70eca962025-05-11 01:48:15 +0800303 [this](mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen) {
304 this->queryDownstreamIdentifiers(eid, response, respMsgLen);
305 });
Unive Tien8b169dc2024-11-25 09:34:39 +0800306 if (rc)
307 {
308 error(
309 "Failed to send QueryDownstreamIdentifiers request for endpoint ID {EID} with response code {RC}",
310 "EID", eid, "RC", rc);
311 }
312}
313
314void InventoryManager::queryDownstreamIdentifiers(
315 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
316{
317 if (!response || !respMsgLen)
318 {
319 error(
320 "No response received for QueryDownstreamIdentifiers for endpoint ID {EID}",
321 "EID", eid);
322 descriptorMap.erase(eid);
323 return;
324 }
325
326 pldm_query_downstream_identifiers_resp downstreamIds{};
327 pldm_downstream_device_iter devs{};
328
329 auto rc = decode_query_downstream_identifiers_resp(response, respMsgLen,
330 &downstreamIds, &devs);
331 if (rc)
332 {
333 error(
334 "Decoding QueryDownstreamIdentifiers response failed for endpoint ID {EID} with response code {RC}",
335 "EID", eid, "RC", rc);
336 return;
337 }
338
339 if (downstreamIds.completion_code)
340 {
341 error(
342 "QueryDownstreamIdentifiers response failed with error completion code for endpoint ID {EID} with completion code {CC}",
343 "EID", eid, "CC", unsigned(downstreamIds.completion_code));
344 return;
345 }
346
347 DownstreamDeviceInfo initialDownstreamDevices{};
348 DownstreamDeviceInfo* downstreamDevices;
349 if (!downstreamDescriptorMap.contains(eid) ||
350 downstreamIds.transfer_flag == PLDM_START ||
351 downstreamIds.transfer_flag == PLDM_START_AND_END)
352 {
353 downstreamDevices = &initialDownstreamDevices;
354 }
355 else
356 {
357 downstreamDevices = &downstreamDescriptorMap.at(eid);
358 }
359
360 pldm_downstream_device dev;
361 foreach_pldm_downstream_device(devs, dev, rc)
362 {
363 pldm_descriptor desc;
364 Descriptors descriptors{};
365 foreach_pldm_downstream_device_descriptor(devs, dev, desc, rc)
366 {
367 const auto descriptorData =
368 new (const_cast<void*>(desc.descriptor_data))
369 uint8_t[desc.descriptor_length];
370 if (desc.descriptor_type != PLDM_FWUP_VENDOR_DEFINED)
371 {
372 std::vector<uint8_t> descData(
373 descriptorData, descriptorData + desc.descriptor_length);
374 descriptors.emplace(desc.descriptor_type, std::move(descData));
375 }
376 else
377 {
378 uint8_t descriptorTitleStrType = 0;
379 variable_field descriptorTitleStr{};
380 variable_field vendorDefinedDescriptorData{};
381
382 rc = decode_vendor_defined_descriptor_value(
383 descriptorData, desc.descriptor_length,
384 &descriptorTitleStrType, &descriptorTitleStr,
385 &vendorDefinedDescriptorData);
386
387 if (rc)
388 {
389 error(
390 "Decoding Vendor-defined descriptor value failed for endpoint ID {EID} with response code {RC}",
391 "EID", eid, "RC", rc);
392 return;
393 }
394
395 auto vendorDefinedDescriptorTitleStr =
396 utils::toString(descriptorTitleStr);
397 std::vector<uint8_t> vendorDescData(
398 vendorDefinedDescriptorData.ptr,
399 vendorDefinedDescriptorData.ptr +
400 vendorDefinedDescriptorData.length);
401 descriptors.emplace(
402 desc.descriptor_type,
403 std::make_tuple(vendorDefinedDescriptorTitleStr,
404 vendorDescData));
405 }
406 }
407 if (rc)
408 {
409 error(
410 "Failed to decode downstream device descriptor for endpoint ID {EID} with response code {RC}",
411 "EID", eid, "RC", rc);
412 return;
413 }
414 downstreamDevices->emplace(dev.downstream_device_index, descriptors);
415 }
416 if (rc)
417 {
418 error(
419 "Failed to decode downstream devices from iterator for endpoint ID {EID} with response code {RC}",
420 "EID", eid, "RC", rc);
421 return;
422 }
423
424 switch (downstreamIds.transfer_flag)
425 {
426 case PLDM_START:
427 downstreamDescriptorMap.insert_or_assign(
428 eid, std::move(initialDownstreamDevices));
429 [[fallthrough]];
430 case PLDM_MIDDLE:
431 sendQueryDownstreamIdentifiersRequest(
432 eid, downstreamIds.next_data_transfer_handle,
433 PLDM_GET_NEXTPART);
434 break;
435 case PLDM_START_AND_END:
436 downstreamDescriptorMap.insert_or_assign(
437 eid, std::move(initialDownstreamDevices));
438 /** DataTransferHandle will be skipped when TransferOperationFlag is
439 * `GetFirstPart`. Use 0x0 as default by following example in
440 * Figure 9 in DSP0267 1.1.0
441 */
442 [[fallthrough]];
443 case PLDM_END:
444 sendGetDownstreamFirmwareParametersRequest(eid, 0x0,
445 PLDM_GET_FIRSTPART);
446 break;
447 }
448}
449
450void InventoryManager::sendGetDownstreamFirmwareParametersRequest(
451 mctp_eid_t eid, uint32_t dataTransferHandle,
452 enum transfer_op_flag transferOperationFlag)
453{
454 Request requestMsg(sizeof(pldm_msg_hdr) +
455 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES);
456 auto instanceId = instanceIdDb.next(eid);
457 auto request = new (requestMsg.data()) pldm_msg;
458 pldm_get_downstream_firmware_parameters_req requestParameters{
459 dataTransferHandle, static_cast<uint8_t>(transferOperationFlag)};
460 auto rc = encode_get_downstream_firmware_parameters_req(
461 instanceId, &requestParameters, request,
462 PLDM_GET_DOWNSTREAM_FIRMWARE_PARAMETERS_REQ_BYTES);
463 if (rc)
464 {
465 instanceIdDb.free(eid, instanceId);
466 error(
467 "Failed to encode query downstream firmware parameters request for endpoint ID {EID} with response code {RC}",
468 "EID", eid, "RC", rc);
469 throw std::runtime_error(
470 "Failed to encode query downstream firmware parameters request");
471 }
472
473 rc = handler.registerRequest(
474 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DOWNSTREAM_FIRMWARE_PARAMETERS,
475 std::move(requestMsg),
Eric Yang70eca962025-05-11 01:48:15 +0800476 [this](mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen) {
477 this->getDownstreamFirmwareParameters(eid, response, respMsgLen);
478 });
Unive Tien8b169dc2024-11-25 09:34:39 +0800479 if (rc)
480 {
481 error(
482 "Failed to send QueryDownstreamFirmwareParameters request for endpoint ID {EID} with response code {RC}",
483 "EID", eid, "RC", rc);
484 }
485}
486
487void InventoryManager::getDownstreamFirmwareParameters(
488 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
489{
490 if (!response || !respMsgLen)
491 {
492 error(
493 "No response received for QueryDownstreamFirmwareParameters for endpoint ID {EID}",
494 "EID", eid);
495 descriptorMap.erase(eid);
496 return;
497 }
498
499 pldm_get_downstream_firmware_parameters_resp resp{};
500 pldm_downstream_device_parameters_iter params{};
501 pldm_downstream_device_parameters_entry entry{};
502
503 auto rc = decode_get_downstream_firmware_parameters_resp(
504 response, respMsgLen, &resp, &params);
505
506 if (rc)
507 {
508 error(
509 "Decoding QueryDownstreamFirmwareParameters response failed for endpoint ID {EID} with response code {RC}",
510 "EID", eid, "RC", rc);
511 return;
512 }
513
514 if (resp.completion_code)
515 {
516 error(
517 "QueryDownstreamFirmwareParameters response failed with error completion code for endpoint ID {EID} with completion code {CC}",
518 "EID", eid, "CC", resp.completion_code);
519 return;
520 }
521
522 foreach_pldm_downstream_device_parameters_entry(params, entry, rc)
523 {
524 // Reserved for upcoming use
525 [[maybe_unused]] variable_field activeCompVerStr{
526 reinterpret_cast<const uint8_t*>(entry.active_comp_ver_str),
527 entry.active_comp_ver_str_len};
528 }
529 if (rc)
530 {
531 error(
532 "Failed to decode downstream device parameters from iterator for endpoint ID {EID} with response code {RC}",
533 "EID", eid, "RC", rc);
534 return;
535 }
536
537 switch (resp.transfer_flag)
538 {
539 case PLDM_START:
540 case PLDM_MIDDLE:
541 sendGetDownstreamFirmwareParametersRequest(
542 eid, resp.next_data_transfer_handle, PLDM_GET_NEXTPART);
543 break;
544 }
545}
546
Tom Joseph75356c12021-06-20 03:52:40 -0700547void InventoryManager::sendGetFirmwareParametersRequest(mctp_eid_t eid)
548{
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930549 auto instanceId = instanceIdDb.next(eid);
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400550 Request requestMsg(
551 sizeof(pldm_msg_hdr) + PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES);
Pavithra Barithaya1039a8a2025-01-31 11:30:14 +0530552 auto request = new (requestMsg.data()) pldm_msg;
Tom Joseph75356c12021-06-20 03:52:40 -0700553 auto rc = encode_get_firmware_parameters_req(
554 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, request);
555 if (rc)
556 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930557 instanceIdDb.free(eid, instanceId);
Riya Dixit76f2c602024-03-28 07:34:12 -0500558 error(
Unive Tien8b169dc2024-11-25 09:34:39 +0800559 "Failed to encode get firmware parameters req for endpoint ID {EID}, response code {RC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500560 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700561 return;
562 }
563
564 rc = handler.registerRequest(
565 eid, instanceId, PLDM_FWUP, PLDM_GET_FIRMWARE_PARAMETERS,
566 std::move(requestMsg),
Eric Yang70eca962025-05-11 01:48:15 +0800567 [this](mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen) {
568 this->getFirmwareParameters(eid, response, respMsgLen);
569 });
Tom Joseph75356c12021-06-20 03:52:40 -0700570 if (rc)
571 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600572 error(
Unive Tien8b169dc2024-11-25 09:34:39 +0800573 "Failed to send get firmware parameters request for endpoint ID {EID}, response code {RC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500574 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700575 }
576}
577
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400578void InventoryManager::getFirmwareParameters(
579 mctp_eid_t eid, const pldm_msg* response, size_t respMsgLen)
Tom Joseph75356c12021-06-20 03:52:40 -0700580{
581 if (response == nullptr || !respMsgLen)
582 {
Riya Dixit76f2c602024-03-28 07:34:12 -0500583 error(
Unive Tien8b169dc2024-11-25 09:34:39 +0800584 "No response received for get firmware parameters for endpoint ID {EID}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500585 "EID", eid);
Tom Joseph75356c12021-06-20 03:52:40 -0700586 descriptorMap.erase(eid);
587 return;
588 }
589
590 pldm_get_firmware_parameters_resp fwParams{};
591 variable_field activeCompImageSetVerStr{};
592 variable_field pendingCompImageSetVerStr{};
593 variable_field compParamTable{};
594
595 auto rc = decode_get_firmware_parameters_resp(
596 response, respMsgLen, &fwParams, &activeCompImageSetVerStr,
597 &pendingCompImageSetVerStr, &compParamTable);
598 if (rc)
599 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600600 error(
Unive Tien8b169dc2024-11-25 09:34:39 +0800601 "Failed to decode get firmware parameters response for endpoint ID {EID}, response code {RC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500602 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700603 return;
604 }
605
606 if (fwParams.completion_code)
607 {
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500608 auto fw_param_cc = fwParams.completion_code;
Riya Dixit49cfb132023-03-02 04:26:53 -0600609 error(
Unive Tien8b169dc2024-11-25 09:34:39 +0800610 "Failed to get firmware parameters response for endpoint ID {EID}, completion code {CC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500611 "EID", eid, "CC", fw_param_cc);
Tom Joseph75356c12021-06-20 03:52:40 -0700612 return;
613 }
614
615 auto compParamPtr = compParamTable.ptr;
616 auto compParamTableLen = compParamTable.length;
617 pldm_component_parameter_entry compEntry{};
618 variable_field activeCompVerStr{};
619 variable_field pendingCompVerStr{};
620
621 ComponentInfo componentInfo{};
622 while (fwParams.comp_count-- && (compParamTableLen > 0))
623 {
624 auto rc = decode_get_firmware_parameters_resp_comp_entry(
625 compParamPtr, compParamTableLen, &compEntry, &activeCompVerStr,
626 &pendingCompVerStr);
627 if (rc)
628 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600629 error(
Unive Tien8b169dc2024-11-25 09:34:39 +0800630 "Failed to decode component parameter table entry for endpoint ID {EID}, response code {RC}",
Riya Dixit1e5c81e2024-05-03 07:54:00 -0500631 "EID", eid, "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700632 return;
633 }
634
635 auto compClassification = compEntry.comp_classification;
636 auto compIdentifier = compEntry.comp_identifier;
637 componentInfo.emplace(
638 std::make_pair(compClassification, compIdentifier),
639 compEntry.comp_classification_index);
640 compParamPtr += sizeof(pldm_component_parameter_entry) +
641 activeCompVerStr.length + pendingCompVerStr.length;
642 compParamTableLen -= sizeof(pldm_component_parameter_entry) +
643 activeCompVerStr.length + pendingCompVerStr.length;
644 }
645 componentInfoMap.emplace(eid, std::move(componentInfo));
646}
647
648} // namespace fw_update
649
Riya Dixit49cfb132023-03-02 04:26:53 -0600650} // namespace pldm