1 #include "pldm_fw_update_cmd.hpp"
2
3 #include "common/utils.hpp"
4 #include "pldm_cmd_helper.hpp"
5
6 #include <libpldm/firmware_update.h>
7
8 namespace pldmtool
9 {
10
11 namespace fw_update
12 {
13
14 namespace
15 {
16
17 using namespace pldmtool::helper;
18 using namespace pldm::fw_update;
19
20 std::vector<std::unique_ptr<CommandInterface>> commands;
21
22 } // namespace
23
24 const std::map<uint8_t, std::string> fdStateMachine{
25 {PLDM_FD_STATE_IDLE, "IDLE"},
26 {PLDM_FD_STATE_LEARN_COMPONENTS, "LEARN COMPONENTS"},
27 {PLDM_FD_STATE_READY_XFER, "READY XFER"},
28 {PLDM_FD_STATE_DOWNLOAD, "DOWNLOAD"},
29 {PLDM_FD_STATE_VERIFY, "VERIFY"},
30 {PLDM_FD_STATE_APPLY, "APPLY"},
31 {PLDM_FD_STATE_ACTIVATE, "ACTIVATE"}};
32
33 const std::map<uint8_t, const char*> fdAuxState{
34 {PLDM_FD_OPERATION_IN_PROGRESS, "Operation in progress"},
35 {PLDM_FD_OPERATION_SUCCESSFUL, "Operation successful"},
36 {PLDM_FD_OPERATION_FAILED, "Operation Failed"},
37 {PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER,
38 "Not applicable in current state"}};
39
40 const std::map<uint8_t, const char*> fdAuxStateStatus{
41 {PLDM_FD_AUX_STATE_IN_PROGRESS_OR_SUCCESS,
42 "AuxState is In Progress or Success"},
43 {PLDM_FD_TIMEOUT, "Timeout occurred while performing action"},
44 {PLDM_FD_GENERIC_ERROR, "Generic Error has occurred"}};
45
46 const std::map<uint8_t, const char*> fdReasonCode{
47 {PLDM_FD_INITIALIZATION, "Initialization of firmware device has occurred"},
48 {PLDM_FD_ACTIVATE_FW, "ActivateFirmware command was received"},
49 {PLDM_FD_CANCEL_UPDATE, "CancelUpdate command was received"},
50 {PLDM_FD_TIMEOUT_LEARN_COMPONENT,
51 "Timeout occurred when in LEARN COMPONENT state"},
52 {PLDM_FD_TIMEOUT_READY_XFER, "Timeout occurred when in READY XFER state"},
53 {PLDM_FD_TIMEOUT_DOWNLOAD, "Timeout occurred when in DOWNLOAD state"},
54 {PLDM_FD_TIMEOUT_VERIFY, "Timeout occurred when in VERIFY state"},
55 {PLDM_FD_TIMEOUT_APPLY, "Timeout occurred when in APPLY state"}};
56
57 /**
58 * @brief descriptor type to name mapping
59 *
60 */
61 const std::map<DescriptorType, const char*> descriptorName{
62 {PLDM_FWUP_PCI_VENDOR_ID, "PCI Vendor ID"},
63 {PLDM_FWUP_IANA_ENTERPRISE_ID, "IANA Enterprise ID"},
64 {PLDM_FWUP_UUID, "UUID"},
65 {PLDM_FWUP_PNP_VENDOR_ID, "PnP Vendor ID"},
66 {PLDM_FWUP_ACPI_VENDOR_ID, "ACPI Vendor ID"},
67 {PLDM_FWUP_PCI_DEVICE_ID, "PCI Device ID"},
68 {PLDM_FWUP_PCI_SUBSYSTEM_VENDOR_ID, "PCI Subsystem Vendor ID"},
69 {PLDM_FWUP_PCI_SUBSYSTEM_ID, "PCI Subsystem ID"},
70 {PLDM_FWUP_PCI_REVISION_ID, "PCI Revision ID"},
71 {PLDM_FWUP_PNP_PRODUCT_IDENTIFIER, "PnP Product Identifier"},
72 {PLDM_FWUP_ACPI_PRODUCT_IDENTIFIER, "ACPI Product Identifier"},
73 {PLDM_FWUP_VENDOR_DEFINED, "Vendor Defined"}};
74
75 class GetStatus : public CommandInterface
76 {
77 public:
78 ~GetStatus() = default;
79 GetStatus() = delete;
80 GetStatus(const GetStatus&) = delete;
81 GetStatus(GetStatus&&) = default;
82 GetStatus& operator=(const GetStatus&) = delete;
83 GetStatus& operator=(GetStatus&&) = delete;
84
85 using CommandInterface::CommandInterface;
86
createRequestMsg()87 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
88 {
89 std::vector<uint8_t> requestMsg(
90 sizeof(pldm_msg_hdr) + PLDM_GET_STATUS_REQ_BYTES);
91 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
92 auto rc = encode_get_status_req(instanceId, request,
93 PLDM_GET_STATUS_REQ_BYTES);
94 return {rc, requestMsg};
95 }
96
parseResponseMsg(pldm_msg * responsePtr,size_t payloadLength)97 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
98 {
99 uint8_t completionCode = 0;
100 uint8_t currentState = 0;
101 uint8_t previousState = 0;
102 uint8_t auxState = 0;
103 uint8_t auxStateStatus = 0;
104 uint8_t progressPercent = 0;
105 uint8_t reasonCode = 0;
106 bitfield32_t updateOptionFlagsEnabled{0};
107
108 auto rc = decode_get_status_resp(
109 responsePtr, payloadLength, &completionCode, ¤tState,
110 &previousState, &auxState, &auxStateStatus, &progressPercent,
111 &reasonCode, &updateOptionFlagsEnabled);
112 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS)
113 {
114 std::cerr << "Response Message Error: "
115 << "rc=" << rc << ",cc=" << (int)completionCode << "\n";
116 return;
117 }
118
119 ordered_json data;
120 data["CurrentState"] = fdStateMachine.at(currentState);
121 data["PreviousState"] = fdStateMachine.at(previousState);
122 data["AuxState"] = fdAuxState.at(auxState);
123 if (auxStateStatus >= PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START &&
124 auxStateStatus <= PLDM_FD_VENDOR_DEFINED_STATUS_CODE_END)
125 {
126 data["AuxStateStatus"] = auxStateStatus;
127 }
128 else
129 {
130 data["AuxStateStatus"] = fdAuxStateStatus.at(auxStateStatus);
131 }
132 data["ProgressPercent"] = progressPercent;
133 if (reasonCode >= PLDM_FD_STATUS_VENDOR_DEFINED_MIN &&
134 reasonCode <= PLDM_FD_STATUS_VENDOR_DEFINED_MAX)
135 {
136 data["ReasonCode"] = reasonCode;
137 }
138 else
139 {
140 data["ReasonCode"] = fdReasonCode.at(reasonCode);
141 }
142 data["UpdateOptionFlagsEnabled"] = updateOptionFlagsEnabled.value;
143
144 pldmtool::helper::DisplayInJson(data);
145 }
146 };
147
148 const std::map<uint16_t, std::string> componentClassification{
149 {PLDM_COMP_UNKNOWN, "Unknown"},
150 {PLDM_COMP_OTHER, "Other"},
151 {PLDM_COMP_DRIVER, "Driver"},
152 {PLDM_COMP_CONFIGURATION_SOFTWARE, "Configuration Software"},
153 {PLDM_COMP_APPLICATION_SOFTWARE, "Application Software"},
154 {PLDM_COMP_INSTRUMENTATION, "Instrumentation"},
155 {PLDM_COMP_FIRMWARE_OR_BIOS, "Firmware/BIOS"},
156 {PLDM_COMP_DIAGNOSTIC_SOFTWARE, "Diagnostic Software"},
157 {PLDM_COMP_OPERATING_SYSTEM, "Operating System"},
158 {PLDM_COMP_MIDDLEWARE, "Middleware"},
159 {PLDM_COMP_FIRMWARE, "Firmware"},
160 {PLDM_COMP_BIOS_OR_FCODE, "BIOS/FCode"},
161 {PLDM_COMP_SUPPORT_OR_SERVICEPACK, "Support/Service Pack"},
162 {PLDM_COMP_SOFTWARE_BUNDLE, "Software Bundle"},
163 {PLDM_COMP_DOWNSTREAM_DEVICE, "Downstream Device"}};
164
165 class GetFwParams : public CommandInterface
166 {
167 public:
168 ~GetFwParams() = default;
169 GetFwParams() = delete;
170 GetFwParams(const GetFwParams&) = delete;
171 GetFwParams(GetFwParams&&) = default;
172 GetFwParams& operator=(const GetFwParams&) = delete;
173 GetFwParams& operator=(GetFwParams&&) = delete;
174
175 using CommandInterface::CommandInterface;
176
createRequestMsg()177 std::pair<int, std::vector<uint8_t>> createRequestMsg() override
178 {
179 std::vector<uint8_t> requestMsg(
180 sizeof(pldm_msg_hdr) + PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES);
181 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
182 auto rc = encode_get_firmware_parameters_req(
183 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, request);
184 return {rc, requestMsg};
185 }
186
parseResponseMsg(pldm_msg * responsePtr,size_t payloadLength)187 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override
188 {
189 pldm_get_firmware_parameters_resp fwParams{};
190 variable_field activeCompImageSetVersion{};
191 variable_field pendingCompImageSetVersion{};
192 variable_field compParameterTable{};
193
194 auto rc = decode_get_firmware_parameters_resp(
195 responsePtr, payloadLength, &fwParams, &activeCompImageSetVersion,
196 &pendingCompImageSetVersion, &compParameterTable);
197 if (rc != PLDM_SUCCESS || fwParams.completion_code != PLDM_SUCCESS)
198 {
199 std::cerr << "Response Message Error: "
200 << "rc=" << rc << ",cc=" << (int)fwParams.completion_code
201 << "\n";
202 return;
203 }
204
205 ordered_json capabilitiesDuringUpdate;
206 if (fwParams.capabilities_during_update.bits.bit0)
207 {
208 capabilitiesDuringUpdate
209 ["Component Update Failure Recovery Capability"] =
210 "Device will not revert to previous component image upon failure, timeout or cancellation of the transfer.";
211 }
212 else
213 {
214 capabilitiesDuringUpdate
215 ["Component Update Failure Recovery Capability"] =
216 "Device will revert to previous component image upon failure, timeout or cancellation of the transfer.";
217 }
218
219 if (fwParams.capabilities_during_update.bits.bit1)
220 {
221 capabilitiesDuringUpdate["Component Update Failure Retry Capability"] =
222 "Device will not be able to update component again unless it exits update mode and the UA sends a new Request Update command.";
223 }
224 else
225 {
226 capabilitiesDuringUpdate["Component Update Failure Retry Capability"] =
227 " Device can have component updated again without exiting update mode and restarting transfer via RequestUpdate command.";
228 }
229
230 if (fwParams.capabilities_during_update.bits.bit2)
231 {
232 capabilitiesDuringUpdate["Firmware Device Partial Updates"] =
233 "Firmware Device can support a partial update, whereby a package which contains a component image set that is a subset of all components currently residing on the FD, can be transferred.";
234 }
235 else
236 {
237 capabilitiesDuringUpdate["Firmware Device Partial Updates"] =
238 "Firmware Device cannot accept a partial update and all components present on the FD shall be updated.";
239 }
240
241 if (fwParams.capabilities_during_update.bits.bit3)
242 {
243 capabilitiesDuringUpdate
244 ["Firmware Device Host Functionality during Firmware Update"] =
245 "Device will not revert to previous component image upon failure, timeout or cancellation of the transfer";
246 }
247 else
248 {
249 capabilitiesDuringUpdate
250 ["Firmware Device Host Functionality during Firmware Update"] =
251 "Device will revert to previous component image upon failure, timeout or cancellation of the transfer";
252 }
253
254 if (fwParams.capabilities_during_update.bits.bit4)
255 {
256 capabilitiesDuringUpdate["Firmware Device Update Mode Restrictions"] =
257 "Firmware device unable to enter update mode if host OS environment is active.";
258 }
259 else
260 {
261 capabilitiesDuringUpdate
262 ["Firmware Device Update Mode Restrictions"] =
263 "No host OS environment restriction for update mode";
264 }
265
266 ordered_json data;
267 data["CapabilitiesDuringUpdate"] = capabilitiesDuringUpdate;
268 data["ComponentCount"] = static_cast<uint16_t>(fwParams.comp_count);
269 data["ActiveComponentImageSetVersionString"] =
270 pldm::utils::toString(activeCompImageSetVersion);
271 data["PendingComponentImageSetVersionString"] =
272 pldm::utils::toString(pendingCompImageSetVersion);
273
274 auto compParamPtr = compParameterTable.ptr;
275 auto compParamTableLen = compParameterTable.length;
276 pldm_component_parameter_entry compEntry{};
277 variable_field activeCompVerStr{};
278 variable_field pendingCompVerStr{};
279 ordered_json compDataEntries;
280
281 while (fwParams.comp_count-- && (compParamTableLen > 0))
282 {
283 ordered_json compData;
284 auto rc = decode_get_firmware_parameters_resp_comp_entry(
285 compParamPtr, compParamTableLen, &compEntry, &activeCompVerStr,
286 &pendingCompVerStr);
287 if (rc)
288 {
289 std::cerr
290 << "Decoding component parameter table entry failed, RC="
291 << rc << "\n";
292 return;
293 }
294
295 if (componentClassification.contains(compEntry.comp_classification))
296 {
297 compData["ComponentClassification"] =
298 componentClassification.at(compEntry.comp_classification);
299 }
300 else
301 {
302 compData["ComponentClassification"] =
303 static_cast<uint16_t>(compEntry.comp_classification);
304 }
305 compData["ComponentIdentifier"] =
306 static_cast<uint16_t>(compEntry.comp_identifier);
307 compData["ComponentClassificationIndex"] =
308 static_cast<uint8_t>(compEntry.comp_classification_index);
309 compData["ActiveComponentComparisonStamp"] =
310 static_cast<uint32_t>(compEntry.active_comp_comparison_stamp);
311
312 // ActiveComponentReleaseData
313 std::array<uint8_t, 8> noReleaseData{0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00};
315 if (std::equal(noReleaseData.begin(), noReleaseData.end(),
316 compEntry.active_comp_release_date))
317 {
318 compData["ActiveComponentReleaseDate"] = "";
319 }
320 else
321 {
322 std::string activeComponentReleaseDate(
323 reinterpret_cast<const char*>(
324 compEntry.active_comp_release_date),
325 sizeof(compEntry.active_comp_release_date));
326 compData["ActiveComponentReleaseDate"] =
327 activeComponentReleaseDate;
328 }
329
330 compData["PendingComponentComparisonStamp"] =
331 static_cast<uint32_t>(compEntry.pending_comp_comparison_stamp);
332
333 // PendingComponentReleaseData
334 if (std::equal(noReleaseData.begin(), noReleaseData.end(),
335 compEntry.pending_comp_release_date))
336 {
337 compData["PendingComponentReleaseDate"] = "";
338 }
339 else
340 {
341 std::string pendingComponentReleaseDate(
342 reinterpret_cast<const char*>(
343 compEntry.pending_comp_release_date),
344 sizeof(compEntry.pending_comp_release_date));
345 compData["PendingComponentReleaseDate"] =
346 pendingComponentReleaseDate;
347 }
348
349 // ComponentActivationMethods
350 ordered_json componentActivationMethods;
351 if (compEntry.comp_activation_methods.bits.bit0)
352 {
353 componentActivationMethods.push_back("Automatic");
354 }
355 else if (compEntry.comp_activation_methods.bits.bit1)
356 {
357 componentActivationMethods.push_back("Self-Contained");
358 }
359 else if (compEntry.comp_activation_methods.bits.bit2)
360 {
361 componentActivationMethods.push_back("Medium-specific reset");
362 }
363 else if (compEntry.comp_activation_methods.bits.bit3)
364 {
365 componentActivationMethods.push_back("System reboot");
366 }
367 else if (compEntry.comp_activation_methods.bits.bit4)
368 {
369 componentActivationMethods.push_back("DC power cycel");
370 }
371 else if (compEntry.comp_activation_methods.bits.bit5)
372 {
373 componentActivationMethods.push_back("AC power cycle");
374 }
375 compData["ComponentActivationMethods"] = componentActivationMethods;
376
377 // CapabilitiesDuringUpdate
378 ordered_json compCapabilitiesDuringUpdate;
379 if (compEntry.capabilities_during_update.bits.bit0)
380 {
381 compCapabilitiesDuringUpdate
382 ["Firmware Device apply state functionality"] =
383 "Firmware Device performs an auto-apply during transfer phase and apply step will be completed immediately.";
384 }
385 else
386 {
387 compCapabilitiesDuringUpdate
388 ["Firmware Device apply state functionality"] =
389 " Firmware Device will execute an operation during the APPLY state which will include migrating the new component image to its final non-volatile storage destination.";
390 }
391 compData["CapabilitiesDuringUpdate"] = compCapabilitiesDuringUpdate;
392
393 compData["ActiveComponentVersionString"] =
394 pldm::utils::toString(activeCompVerStr);
395 compData["PendingComponentVersionString"] =
396 pldm::utils::toString(pendingCompVerStr);
397
398 compParamPtr += sizeof(pldm_component_parameter_entry) +
399 activeCompVerStr.length + pendingCompVerStr.length;
400 compParamTableLen -=
401 sizeof(pldm_component_parameter_entry) +
402 activeCompVerStr.length + pendingCompVerStr.length;
403 compDataEntries.push_back(compData);
404 }
405 data["ComponentParameterEntries"] = compDataEntries;
406
407 pldmtool::helper::DisplayInJson(data);
408 }
409 };
410
411 class QueryDeviceIdentifiers : public CommandInterface
412 {
413 public:
414 ~QueryDeviceIdentifiers() = default;
415 QueryDeviceIdentifiers() = delete;
416 QueryDeviceIdentifiers(const QueryDeviceIdentifiers&) = delete;
417 QueryDeviceIdentifiers(QueryDeviceIdentifiers&&) = default;
418 QueryDeviceIdentifiers& operator=(const QueryDeviceIdentifiers&) = delete;
419 QueryDeviceIdentifiers& operator=(QueryDeviceIdentifiers&&) = delete;
420
421 /**
422 * @brief Implementation of createRequestMsg for QueryDeviceIdentifiers
423 *
424 * @return std::pair<int, std::vector<uint8_t>>
425 */
426 std::pair<int, std::vector<uint8_t>> createRequestMsg() override;
427
428 /**
429 * @brief Implementation of parseResponseMsg for QueryDeviceIdentifiers
430 *
431 * @param[in] responsePtr
432 * @param[in] payloadLength
433 */
434 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override;
435 using CommandInterface::CommandInterface;
436
437 private:
438 /**
439 * @brief Method to update QueryDeviceIdentifiers json response in a user
440 * friendly format
441 *
442 * @param[in] descriptors - descriptor json response
443 * @param[in] descriptorType - descriptor type
444 * @param[in] descriptorVal - descriptor value
445 */
446 void updateDescriptor(
447 ordered_json& descriptors, const DescriptorType& descriptorType,
448 const std::variant<DescriptorData, VendorDefinedDescriptorInfo>&
449 descriptorVal);
450 };
451
updateDescriptor(ordered_json & descriptors,const DescriptorType & descriptorType,const std::variant<DescriptorData,VendorDefinedDescriptorInfo> & descriptorVal)452 void QueryDeviceIdentifiers::updateDescriptor(
453 ordered_json& descriptors, const DescriptorType& descriptorType,
454 const std::variant<DescriptorData, VendorDefinedDescriptorInfo>&
455 descriptorVal)
456 {
457 std::ostringstream descDataStream;
458 DescriptorData descData;
459 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
460 {
461 descData = std::get<DescriptorData>(descriptorVal);
462 }
463 else
464 {
465 descData = std::get<VendorDefinedDescriptorData>(
466 std::get<VendorDefinedDescriptorInfo>(descriptorVal));
467 }
468 for (int byte : descData)
469 {
470 descDataStream << std::setfill('0') << std::setw(2) << std::hex << byte;
471 }
472
473 if (descriptorName.contains(descriptorType))
474 {
475 // Update the existing json response if entry is already present
476 for (auto& descriptor : descriptors)
477 {
478 if (descriptor["Type"] == descriptorName.at(descriptorType))
479 {
480 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
481 {
482 descriptor["Value"].emplace_back(descDataStream.str());
483 }
484 else
485 {
486 ordered_json vendorDefinedVal;
487 vendorDefinedVal[std::get<VendorDefinedDescriptorTitle>(
488 std::get<VendorDefinedDescriptorInfo>(descriptorVal))] =
489 descDataStream.str();
490 descriptor["Value"].emplace_back(vendorDefinedVal);
491 }
492 return;
493 }
494 }
495 // Entry is not present, add type and value to json response
496 ordered_json descriptor = ordered_json::object(
497 {{"Type", descriptorName.at(descriptorType)},
498 {"Value", ordered_json::array()}});
499 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
500 {
501 descriptor["Value"].emplace_back(descDataStream.str());
502 }
503 else
504 {
505 ordered_json vendorDefinedVal;
506 vendorDefinedVal[std::get<VendorDefinedDescriptorTitle>(
507 std::get<VendorDefinedDescriptorInfo>(descriptorVal))] =
508 descDataStream.str();
509 descriptor["Value"].emplace_back(vendorDefinedVal);
510 }
511 descriptors.emplace_back(descriptor);
512 }
513 else
514 {
515 std::cerr << "Unknown descriptor type, type=" << descriptorType << "\n";
516 }
517 }
createRequestMsg()518 std::pair<int, std::vector<uint8_t>> QueryDeviceIdentifiers::createRequestMsg()
519 {
520 std::vector<uint8_t> requestMsg(
521 sizeof(pldm_msg_hdr) + PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES);
522 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
523 auto rc = encode_query_device_identifiers_req(
524 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, request);
525 return {rc, requestMsg};
526 }
527
parseResponseMsg(pldm_msg * responsePtr,size_t payloadLength)528 void QueryDeviceIdentifiers::parseResponseMsg(pldm_msg* responsePtr,
529 size_t payloadLength)
530 {
531 uint8_t completionCode = PLDM_SUCCESS;
532 uint32_t deviceIdentifiersLen = 0;
533 uint8_t descriptorCount = 0;
534 uint8_t* descriptorPtr = nullptr;
535 uint8_t eid = getMCTPEID();
536 auto rc = decode_query_device_identifiers_resp(
537 responsePtr, payloadLength, &completionCode, &deviceIdentifiersLen,
538 &descriptorCount, &descriptorPtr);
539 if (rc)
540 {
541 std::cerr << "Decoding QueryDeviceIdentifiers response failed,EID="
542 << unsigned(eid) << ", RC=" << rc << "\n";
543 return;
544 }
545 if (completionCode)
546 {
547 std::cerr << "QueryDeviceIdentifiers response failed with error "
548 "completion code, EID="
549 << unsigned(eid) << ", CC=" << unsigned(completionCode)
550 << "\n";
551 return;
552 }
553 ordered_json data;
554 data["EID"] = eid;
555 ordered_json descriptors;
556 while (descriptorCount-- && (deviceIdentifiersLen > 0))
557 {
558 DescriptorType descriptorType = 0;
559 variable_field descriptorData{};
560
561 rc = decode_descriptor_type_length_value(
562 descriptorPtr, deviceIdentifiersLen, &descriptorType,
563 &descriptorData);
564 if (rc)
565 {
566 std::cerr << "Decoding descriptor type, length and value failed,"
567 << "EID=" << unsigned(eid) << ",RC=" << rc << "\n ";
568 return;
569 }
570
571 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
572 {
573 std::vector<uint8_t> descData(
574 descriptorData.ptr, descriptorData.ptr + descriptorData.length);
575 updateDescriptor(descriptors, descriptorType, descData);
576 }
577 else
578 {
579 uint8_t descriptorTitleStrType = 0;
580 variable_field descriptorTitleStr{};
581 variable_field vendorDefinedDescriptorData{};
582
583 rc = decode_vendor_defined_descriptor_value(
584 descriptorData.ptr, descriptorData.length,
585 &descriptorTitleStrType, &descriptorTitleStr,
586 &vendorDefinedDescriptorData);
587 if (rc)
588 {
589 std::cerr << "Decoding Vendor-defined descriptor value"
590 << "failed EID=" << unsigned(eid) << ", RC=" << rc
591 << "\n ";
592 return;
593 }
594
595 auto vendorDescTitle = pldm::utils::toString(descriptorTitleStr);
596 std::vector<uint8_t> vendorDescData(
597 vendorDefinedDescriptorData.ptr,
598 vendorDefinedDescriptorData.ptr +
599 vendorDefinedDescriptorData.length);
600 updateDescriptor(descriptors, descriptorType,
601 std::make_tuple(vendorDescTitle, vendorDescData));
602 }
603 auto nextDescriptorOffset =
604 sizeof(pldm_descriptor_tlv().descriptor_type) +
605 sizeof(pldm_descriptor_tlv().descriptor_length) +
606 descriptorData.length;
607 descriptorPtr += nextDescriptorOffset;
608 deviceIdentifiersLen -= nextDescriptorOffset;
609 }
610 data["Descriptors"] = descriptors;
611 pldmtool::helper::DisplayInJson(data);
612 }
613
registerCommand(CLI::App & app)614 void registerCommand(CLI::App& app)
615 {
616 auto fwUpdate =
617 app.add_subcommand("fw_update", "firmware update type commands");
618 fwUpdate->require_subcommand(1);
619
620 auto getStatus = fwUpdate->add_subcommand("GetStatus", "Status of the FD");
621 commands.push_back(
622 std::make_unique<GetStatus>("fw_update", "GetStatus", getStatus));
623
624 auto getFwParams = fwUpdate->add_subcommand(
625 "GetFwParams", "To get the component details of the FD");
626 commands.push_back(
627 std::make_unique<GetFwParams>("fw_update", "GetFwParams", getFwParams));
628
629 auto queryDeviceIdentifiers = fwUpdate->add_subcommand(
630 "QueryDeviceIdentifiers", "To query device identifiers of the FD");
631 commands.push_back(std::make_unique<QueryDeviceIdentifiers>(
632 "fw_update", "QueryDeviceIdentifiers", queryDeviceIdentifiers));
633 }
634
635 } // namespace fw_update
636
637 } // namespace pldmtool
638