| Lakshminarayana R. Kammath | 27693a4 | 2019-06-24 00:51:47 -0500 | [diff] [blame] | 1 | #include "pldm_cmd_helper.hpp" | 
|  | 2 |  | 
| Rashmica Gupta | 1ed5f7a | 2023-05-22 13:56:42 +1000 | [diff] [blame] | 3 | #include "common/transport.hpp" | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 4 | #include "xyz/openbmc_project/Common/error.hpp" | 
|  | 5 |  | 
| rajeeranjan | 72512e6 | 2025-03-25 15:16:36 +0530 | [diff] [blame] | 6 | #include <libpldm/firmware_update.h> | 
| Rashmica Gupta | 1ed5f7a | 2023-05-22 13:56:42 +1000 | [diff] [blame] | 7 | #include <libpldm/transport.h> | 
|  | 8 | #include <libpldm/transport/af-mctp.h> | 
|  | 9 | #include <libpldm/transport/mctp-demux.h> | 
|  | 10 | #include <poll.h> | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 11 | #include <systemd/sd-bus.h> | 
|  | 12 |  | 
| Pavithra Barithaya | ac3c45a | 2020-03-05 02:28:26 -0600 | [diff] [blame] | 13 | #include <sdbusplus/server.hpp> | 
|  | 14 | #include <xyz/openbmc_project/Logging/Entry/server.hpp> | 
|  | 15 |  | 
| George Liu | 6492f52 | 2020-06-16 10:34:05 +0800 | [diff] [blame] | 16 | #include <exception> | 
| Pavithra Barithaya | f5ad6c7 | 2019-12-06 15:10:52 +0800 | [diff] [blame] | 17 |  | 
| Brad Bishop | 5079ac4 | 2021-08-19 18:35:06 -0400 | [diff] [blame] | 18 | using namespace pldm::utils; | 
|  | 19 |  | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 20 | namespace pldmtool | 
|  | 21 | { | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 22 | namespace helper | 
|  | 23 | { | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 24 |  | 
| rajeeranjan | 72512e6 | 2025-03-25 15:16:36 +0530 | [diff] [blame] | 25 | static const std::map<uint8_t, std::string> genericCompletionCodes{ | 
|  | 26 | {PLDM_SUCCESS, "SUCCESS"}, | 
|  | 27 | {PLDM_ERROR, "ERROR"}, | 
|  | 28 | {PLDM_ERROR_INVALID_DATA, "ERROR_INVALID_DATA"}, | 
|  | 29 | {PLDM_ERROR_INVALID_LENGTH, "ERROR_INVALID_LENGTH"}, | 
|  | 30 | {PLDM_ERROR_NOT_READY, "ERROR_NOT_READY"}, | 
|  | 31 | {PLDM_ERROR_UNSUPPORTED_PLDM_CMD, "ERROR_UNSUPPORTED_PLDM_CMD"}, | 
|  | 32 | {PLDM_ERROR_INVALID_PLDM_TYPE, "ERROR_INVALID_PLDM_TYPE"}, | 
| Manojkiran Eda | 9285b6b | 2025-06-12 13:09:14 +0530 | [diff] [blame] | 33 | {PLDM_ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION, | 
|  | 34 | "ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION"}}; | 
| rajeeranjan | 72512e6 | 2025-03-25 15:16:36 +0530 | [diff] [blame] | 35 |  | 
|  | 36 | static const std::map<uint8_t, std::string> fwupdateCompletionCodes{ | 
|  | 37 | {PLDM_FWUP_NOT_IN_UPDATE_MODE, "NOT_IN_UPDATE_MODE"}, | 
|  | 38 | {PLDM_FWUP_ALREADY_IN_UPDATE_MODE, "ALREADY_IN_UPDATE_MODE"}, | 
|  | 39 | {PLDM_FWUP_DATA_OUT_OF_RANGE, "DATA_OUT_OF_RANGE"}, | 
|  | 40 | {PLDM_FWUP_INVALID_TRANSFER_LENGTH, "INVALID_TRANSFER_LENGTH"}, | 
|  | 41 | {PLDM_FWUP_INVALID_STATE_FOR_COMMAND, "INVALID_STATE_FOR_COMMAND"}, | 
|  | 42 | {PLDM_FWUP_INCOMPLETE_UPDATE, "INCOMPLETE_UPDATE"}, | 
|  | 43 | {PLDM_FWUP_BUSY_IN_BACKGROUND, "BUSY_IN_BACKGROUND"}, | 
|  | 44 | {PLDM_FWUP_CANCEL_PENDING, "CANCEL_PENDING"}, | 
|  | 45 | {PLDM_FWUP_COMMAND_NOT_EXPECTED, "COMMAND_NOT_EXPECTED"}, | 
|  | 46 | {PLDM_FWUP_RETRY_REQUEST_FW_DATA, "RETRY_REQUEST_FW_DATA"}, | 
|  | 47 | {PLDM_FWUP_UNABLE_TO_INITIATE_UPDATE, "UNABLE_TO_INITIATE_UPDATE"}, | 
|  | 48 | {PLDM_FWUP_ACTIVATION_NOT_REQUIRED, "ACTIVATION_NOT_REQUIRED"}, | 
|  | 49 | {PLDM_FWUP_SELF_CONTAINED_ACTIVATION_NOT_PERMITTED, | 
|  | 50 | "SELF_CONTAINED_ACTIVATION_NOT_PERMITTED"}, | 
|  | 51 | {PLDM_FWUP_NO_DEVICE_METADATA, "NO_DEVICE_METADATA"}, | 
|  | 52 | {PLDM_FWUP_RETRY_REQUEST_UPDATE, "RETRY_REQUEST_UPDATE"}, | 
|  | 53 | {PLDM_FWUP_NO_PACKAGE_DATA, "NO_PACKAGE_DATA"}, | 
|  | 54 | {PLDM_FWUP_INVALID_TRANSFER_HANDLE, "INVALID_TRANSFER_HANDLE"}, | 
|  | 55 | {PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG, | 
|  | 56 | "INVALID_TRANSFER_OPERATION_FLAG"}, | 
|  | 57 | {PLDM_FWUP_ACTIVATE_PENDING_IMAGE_NOT_PERMITTED, | 
|  | 58 | "ACTIVATE_PENDING_IMAGE_NOT_PERMITTED"}, | 
|  | 59 | {PLDM_FWUP_PACKAGE_DATA_ERROR, "PACKAGE_DATA_ERROR"}}; | 
|  | 60 |  | 
|  | 61 | void fillCompletionCode(uint8_t completionCode, ordered_json& data, | 
|  | 62 | uint8_t pldmType) | 
|  | 63 | { | 
|  | 64 | // Check generic completion codes first for all PLDM types | 
|  | 65 | auto it = genericCompletionCodes.find(completionCode); | 
|  | 66 | if (it != genericCompletionCodes.end()) | 
|  | 67 | { | 
|  | 68 | data["CompletionCode"] = it->second; | 
|  | 69 | return; | 
|  | 70 | } | 
|  | 71 |  | 
|  | 72 | // If not a generic code, check type-specific codes | 
|  | 73 | switch (pldmType) | 
|  | 74 | { | 
|  | 75 | case PLDM_FWUP: | 
|  | 76 | { | 
|  | 77 | auto typeIt = fwupdateCompletionCodes.find(completionCode); | 
|  | 78 | if (typeIt != fwupdateCompletionCodes.end()) | 
|  | 79 | { | 
|  | 80 | data["CompletionCode"] = typeIt->second; | 
|  | 81 | return; | 
|  | 82 | } | 
|  | 83 | break; | 
|  | 84 | } | 
|  | 85 | } | 
|  | 86 |  | 
|  | 87 | data["CompletionCode"] = "UNKNOWN_COMPLETION_CODE"; | 
|  | 88 | } | 
|  | 89 |  | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 90 | void CommandInterface::exec() | 
|  | 91 | { | 
| ManojKiran Eda | 22bcb07 | 2025-07-11 23:49:43 +0000 | [diff] [blame] | 92 | instanceId = instanceIdDb.next(mctp_eid); | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 93 | auto [rc, requestMsg] = createRequestMsg(); | 
|  | 94 | if (rc != PLDM_SUCCESS) | 
|  | 95 | { | 
| Dung Cao | 3d03f3f | 2023-09-07 06:51:33 +0000 | [diff] [blame] | 96 | instanceIdDb.free(mctp_eid, instanceId); | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 97 | std::cerr << "Failed to encode request message for " << pldmType << ":" | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 98 | << commandName << " rc = " << rc << "\n"; | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 99 | return; | 
|  | 100 | } | 
|  | 101 |  | 
| John Wang | b754eee | 2020-02-15 16:10:25 +0800 | [diff] [blame] | 102 | std::vector<uint8_t> responseMsg; | 
|  | 103 | rc = pldmSendRecv(requestMsg, responseMsg); | 
|  | 104 |  | 
|  | 105 | if (rc != PLDM_SUCCESS) | 
|  | 106 | { | 
| Dung Cao | 3d03f3f | 2023-09-07 06:51:33 +0000 | [diff] [blame] | 107 | instanceIdDb.free(mctp_eid, instanceId); | 
| John Wang | b754eee | 2020-02-15 16:10:25 +0800 | [diff] [blame] | 108 | std::cerr << "pldmSendRecv: Failed to receive RC = " << rc << "\n"; | 
|  | 109 | return; | 
|  | 110 | } | 
|  | 111 |  | 
|  | 112 | auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg.data()); | 
|  | 113 | parseResponseMsg(responsePtr, responseMsg.size() - sizeof(pldm_msg_hdr)); | 
| Dung Cao | 3d03f3f | 2023-09-07 06:51:33 +0000 | [diff] [blame] | 114 | instanceIdDb.free(mctp_eid, instanceId); | 
| John Wang | b754eee | 2020-02-15 16:10:25 +0800 | [diff] [blame] | 115 | } | 
|  | 116 |  | 
|  | 117 | int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg, | 
|  | 118 | std::vector<uint8_t>& responseMsg) | 
|  | 119 | { | 
| Sridevi Ramesh | c91822b | 2020-02-27 09:26:41 -0600 | [diff] [blame] | 120 | // By default enable request/response msgs for pldmtool raw commands. | 
|  | 121 | if (CommandInterface::pldmType == "raw") | 
|  | 122 | { | 
|  | 123 | pldmVerbose = true; | 
|  | 124 | } | 
|  | 125 |  | 
| Tom Joseph | e5268cd | 2021-09-07 13:04:03 +0530 | [diff] [blame] | 126 | if (pldmVerbose) | 
|  | 127 | { | 
|  | 128 | std::cout << "pldmtool: "; | 
|  | 129 | printBuffer(Tx, requestMsg); | 
|  | 130 | } | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 131 |  | 
| Rashmica Gupta | 1ed5f7a | 2023-05-22 13:56:42 +1000 | [diff] [blame] | 132 | auto tid = mctp_eid; | 
| Amithash Prasad | e7ae804 | 2025-09-11 13:47:05 -0700 | [diff] [blame^] | 133 | PldmTransport pldmTransport(false); | 
| Thu Nguyen | 9427089 | 2023-10-25 17:11:44 +0700 | [diff] [blame] | 134 | uint8_t retry = 0; | 
|  | 135 | int rc = PLDM_ERROR; | 
| Rashmica Gupta | 1ed5f7a | 2023-05-22 13:56:42 +1000 | [diff] [blame] | 136 |  | 
| Thu Nguyen | 9427089 | 2023-10-25 17:11:44 +0700 | [diff] [blame] | 137 | while (PLDM_REQUESTER_SUCCESS != rc && retry <= numRetries) | 
|  | 138 | { | 
|  | 139 | void* responseMessage = nullptr; | 
|  | 140 | size_t responseMessageSize{}; | 
|  | 141 |  | 
| Patrick Williams | 16c2a0a | 2024-08-16 15:20:59 -0400 | [diff] [blame] | 142 | rc = | 
|  | 143 | pldmTransport.sendRecvMsg(tid, requestMsg.data(), requestMsg.size(), | 
|  | 144 | responseMessage, responseMessageSize); | 
| Thu Nguyen | 9427089 | 2023-10-25 17:11:44 +0700 | [diff] [blame] | 145 | if (rc) | 
|  | 146 | { | 
|  | 147 | std::cerr << "[" << unsigned(retry) << "] pldm_send_recv error rc " | 
|  | 148 | << rc << std::endl; | 
|  | 149 | retry++; | 
|  | 150 | continue; | 
|  | 151 | } | 
|  | 152 |  | 
|  | 153 | responseMsg.resize(responseMessageSize); | 
|  | 154 | memcpy(responseMsg.data(), responseMessage, responseMsg.size()); | 
|  | 155 |  | 
|  | 156 | free(responseMessage); | 
|  | 157 |  | 
|  | 158 | if (pldmVerbose) | 
|  | 159 | { | 
|  | 160 | std::cout << "pldmtool: "; | 
|  | 161 | printBuffer(Rx, responseMsg); | 
|  | 162 | } | 
|  | 163 | } | 
|  | 164 |  | 
| Rashmica Gupta | 1ed5f7a | 2023-05-22 13:56:42 +1000 | [diff] [blame] | 165 | if (rc) | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 166 | { | 
| Thu Nguyen | 9427089 | 2023-10-25 17:11:44 +0700 | [diff] [blame] | 167 | std::cerr << "failed to pldm send recv error rc " << rc << std::endl; | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 168 | } | 
| Rashmica Gupta | 1ed5f7a | 2023-05-22 13:56:42 +1000 | [diff] [blame] | 169 |  | 
| Thu Nguyen | 9427089 | 2023-10-25 17:11:44 +0700 | [diff] [blame] | 170 | return rc; | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 171 | } | 
| John Wang | 58a0e06 | 2019-11-08 15:38:15 +0800 | [diff] [blame] | 172 | } // namespace helper | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 173 | } // namespace pldmtool |