Tom Joseph | eea835a | 2021-10-25 19:30:32 +0530 | [diff] [blame] | 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 |