1 #include "pldm_fw_update_cmd.hpp" 2 3 #include "libpldm/firmware_update.h" 4 5 #include "common/utils.hpp" 6 #include "pldm_cmd_helper.hpp" 7 8 namespace pldmtool 9 { 10 11 namespace fw_update 12 { 13 14 namespace 15 { 16 17 using namespace pldmtool::helper; 18 19 std::vector<std::unique_ptr<CommandInterface>> commands; 20 21 } // namespace 22 23 const std::map<uint8_t, std::string> fdStateMachine{ 24 {PLDM_FD_STATE_IDLE, "IDLE"}, 25 {PLDM_FD_STATE_LEARN_COMPONENTS, "LEARN COMPONENTS"}, 26 {PLDM_FD_STATE_READY_XFER, "READY XFER"}, 27 {PLDM_FD_STATE_DOWNLOAD, "DOWNLOAD"}, 28 {PLDM_FD_STATE_VERIFY, "VERIFY"}, 29 {PLDM_FD_STATE_APPLY, "APPLY"}, 30 {PLDM_FD_STATE_ACTIVATE, "ACTIVATE"}}; 31 32 const std::map<uint8_t, const char*> fdAuxState{ 33 {PLDM_FD_OPERATION_IN_PROGRESS, "Operation in progress"}, 34 {PLDM_FD_OPERATION_SUCCESSFUL, "Operation successful"}, 35 {PLDM_FD_OPERATION_FAILED, "Operation Failed"}, 36 {PLDM_FD_IDLE_LEARN_COMPONENTS_READ_XFER, 37 "Not applicable in current state"}}; 38 39 const std::map<uint8_t, const char*> fdAuxStateStatus{ 40 {PLDM_FD_AUX_STATE_IN_PROGRESS_OR_SUCCESS, 41 "AuxState is In Progress or Success"}, 42 {PLDM_FD_TIMEOUT, "Timeout occurred while performing action"}, 43 {PLDM_FD_GENERIC_ERROR, "Generic Error has occured"}}; 44 45 const std::map<uint8_t, const char*> fdReasonCode{ 46 {PLDM_FD_INITIALIZATION, "Initialization of firmware device has occurred"}, 47 {PLDM_FD_ACTIVATE_FW, "ActivateFirmware command was received"}, 48 {PLDM_FD_CANCEL_UPDATE, "CancelUpdate command was received"}, 49 {PLDM_FD_TIMEOUT_LEARN_COMPONENT, 50 "Timeout occurred when in LEARN COMPONENT state"}, 51 {PLDM_FD_TIMEOUT_READY_XFER, "Timeout occurred when in READY XFER state"}, 52 {PLDM_FD_TIMEOUT_DOWNLOAD, "Timeout occurred when in DOWNLOAD state"}, 53 {PLDM_FD_TIMEOUT_VERIFY, "Timeout occurred when in VERIFY state"}, 54 {PLDM_FD_TIMEOUT_APPLY, "Timeout occurred when in APPLY state"}}; 55 56 class GetStatus : public CommandInterface 57 { 58 public: 59 ~GetStatus() = default; 60 GetStatus() = delete; 61 GetStatus(const GetStatus&) = delete; 62 GetStatus(GetStatus&&) = default; 63 GetStatus& operator=(const GetStatus&) = delete; 64 GetStatus& operator=(GetStatus&&) = default; 65 66 using CommandInterface::CommandInterface; 67 68 std::pair<int, std::vector<uint8_t>> createRequestMsg() override 69 { 70 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 71 PLDM_GET_STATUS_REQ_BYTES); 72 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 73 auto rc = encode_get_status_req(instanceId, request, 74 PLDM_GET_STATUS_REQ_BYTES); 75 return {rc, requestMsg}; 76 } 77 78 void parseResponseMsg(pldm_msg* responsePtr, size_t payloadLength) override 79 { 80 uint8_t completionCode = 0; 81 uint8_t currentState = 0; 82 uint8_t previousState = 0; 83 uint8_t auxState = 0; 84 uint8_t auxStateStatus = 0; 85 uint8_t progressPercent = 0; 86 uint8_t reasonCode = 0; 87 bitfield32_t updateOptionFlagsEnabled{0}; 88 89 auto rc = decode_get_status_resp( 90 responsePtr, payloadLength, &completionCode, ¤tState, 91 &previousState, &auxState, &auxStateStatus, &progressPercent, 92 &reasonCode, &updateOptionFlagsEnabled); 93 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS) 94 { 95 std::cerr << "Response Message Error: " 96 << "rc=" << rc << ",cc=" << (int)completionCode << "\n"; 97 return; 98 } 99 100 ordered_json data; 101 data["CurrentState"] = fdStateMachine.at(currentState); 102 data["PreviousState"] = fdStateMachine.at(previousState); 103 data["AuxState"] = fdAuxState.at(auxState); 104 if (auxStateStatus >= PLDM_FD_VENDOR_DEFINED_STATUS_CODE_START && 105 auxStateStatus <= PLDM_FD_VENDOR_DEFINED_STATUS_CODE_END) 106 { 107 data["AuxStateStatus"] = auxStateStatus; 108 } 109 else 110 { 111 data["AuxStateStatus"] = fdAuxStateStatus.at(auxStateStatus); 112 } 113 data["ProgressPercent"] = progressPercent; 114 if (reasonCode >= PLDM_FD_STATUS_VENDOR_DEFINED_MIN && 115 reasonCode <= PLDM_FD_STATUS_VENDOR_DEFINED_MAX) 116 { 117 data["ReasonCode"] = reasonCode; 118 } 119 else 120 { 121 data["ReasonCode"] = fdReasonCode.at(reasonCode); 122 } 123 data["UpdateOptionFlagsEnabled"] = updateOptionFlagsEnabled.value; 124 125 pldmtool::helper::DisplayInJson(data); 126 } 127 }; 128 129 void registerCommand(CLI::App& app) 130 { 131 auto fwUpdate = 132 app.add_subcommand("fw_update", "firmware update type commands"); 133 fwUpdate->require_subcommand(1); 134 135 auto getStatus = fwUpdate->add_subcommand("GetStatus", "Status of the FD"); 136 commands.push_back( 137 std::make_unique<GetStatus>("fw_update", "GetStatus", getStatus)); 138 } 139 140 } // namespace fw_update 141 142 } // namespace pldmtool