blob: 54260e7e367795baed2870657cc1c4bf219b8784 [file] [log] [blame]
Lakshminarayana R. Kammath27693a42019-06-24 00:51:47 -05001#include "pldm_cmd_helper.hpp"
2
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +10003#include "common/transport.hpp"
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -06004#include "xyz/openbmc_project/Common/error.hpp"
5
rajeeranjan72512e62025-03-25 15:16:36 +05306#include <libpldm/firmware_update.h>
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +10007#include <libpldm/transport.h>
8#include <libpldm/transport/af-mctp.h>
9#include <libpldm/transport/mctp-demux.h>
10#include <poll.h>
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060011#include <systemd/sd-bus.h>
12
Pavithra Barithayaac3c45a2020-03-05 02:28:26 -060013#include <sdbusplus/server.hpp>
14#include <xyz/openbmc_project/Logging/Entry/server.hpp>
15
George Liu6492f522020-06-16 10:34:05 +080016#include <exception>
Pavithra Barithayaf5ad6c72019-12-06 15:10:52 +080017
Brad Bishop5079ac42021-08-19 18:35:06 -040018using namespace pldm::utils;
19
John Wang58a0e062019-11-08 15:38:15 +080020namespace pldmtool
21{
John Wang58a0e062019-11-08 15:38:15 +080022namespace helper
23{
John Wang58a0e062019-11-08 15:38:15 +080024
rajeeranjan72512e62025-03-25 15:16:36 +053025static 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 Eda9285b6b2025-06-12 13:09:14 +053033 {PLDM_ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION,
34 "ERROR_UNEXPECTED_TRANSFER_FLAG_OPERATION"}};
rajeeranjan72512e62025-03-25 15:16:36 +053035
36static 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
61void 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 Wang58a0e062019-11-08 15:38:15 +080090void CommandInterface::exec()
91{
Eric Yang70262ed2025-07-02 06:35:03 +000092 auto instanceIdResult =
93 pldm::utils::getInstanceId(instanceIdDb.next(mctp_eid));
94 if (!instanceIdResult)
95 {
96 return;
97 }
98 auto instanceId = instanceIdResult.value();
John Wang58a0e062019-11-08 15:38:15 +080099 auto [rc, requestMsg] = createRequestMsg();
100 if (rc != PLDM_SUCCESS)
101 {
Dung Cao3d03f3f2023-09-07 06:51:33 +0000102 instanceIdDb.free(mctp_eid, instanceId);
John Wang58a0e062019-11-08 15:38:15 +0800103 std::cerr << "Failed to encode request message for " << pldmType << ":"
Sampa Misraaa8ae722019-12-12 03:20:40 -0600104 << commandName << " rc = " << rc << "\n";
John Wang58a0e062019-11-08 15:38:15 +0800105 return;
106 }
107
John Wangb754eee2020-02-15 16:10:25 +0800108 std::vector<uint8_t> responseMsg;
109 rc = pldmSendRecv(requestMsg, responseMsg);
110
111 if (rc != PLDM_SUCCESS)
112 {
Dung Cao3d03f3f2023-09-07 06:51:33 +0000113 instanceIdDb.free(mctp_eid, instanceId);
John Wangb754eee2020-02-15 16:10:25 +0800114 std::cerr << "pldmSendRecv: Failed to receive RC = " << rc << "\n";
115 return;
116 }
117
118 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg.data());
119 parseResponseMsg(responsePtr, responseMsg.size() - sizeof(pldm_msg_hdr));
Dung Cao3d03f3f2023-09-07 06:51:33 +0000120 instanceIdDb.free(mctp_eid, instanceId);
John Wangb754eee2020-02-15 16:10:25 +0800121}
122
123int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
124 std::vector<uint8_t>& responseMsg)
125{
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600126 // By default enable request/response msgs for pldmtool raw commands.
127 if (CommandInterface::pldmType == "raw")
128 {
129 pldmVerbose = true;
130 }
131
Tom Josephe5268cd2021-09-07 13:04:03 +0530132 if (pldmVerbose)
133 {
134 std::cout << "pldmtool: ";
135 printBuffer(Tx, requestMsg);
136 }
John Wang58a0e062019-11-08 15:38:15 +0800137
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000138 auto tid = mctp_eid;
139 PldmTransport pldmTransport{};
Thu Nguyen94270892023-10-25 17:11:44 +0700140 uint8_t retry = 0;
141 int rc = PLDM_ERROR;
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000142
Thu Nguyen94270892023-10-25 17:11:44 +0700143 while (PLDM_REQUESTER_SUCCESS != rc && retry <= numRetries)
144 {
145 void* responseMessage = nullptr;
146 size_t responseMessageSize{};
147
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400148 rc =
149 pldmTransport.sendRecvMsg(tid, requestMsg.data(), requestMsg.size(),
150 responseMessage, responseMessageSize);
Thu Nguyen94270892023-10-25 17:11:44 +0700151 if (rc)
152 {
153 std::cerr << "[" << unsigned(retry) << "] pldm_send_recv error rc "
154 << rc << std::endl;
155 retry++;
156 continue;
157 }
158
159 responseMsg.resize(responseMessageSize);
160 memcpy(responseMsg.data(), responseMessage, responseMsg.size());
161
162 free(responseMessage);
163
164 if (pldmVerbose)
165 {
166 std::cout << "pldmtool: ";
167 printBuffer(Rx, responseMsg);
168 }
169 }
170
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000171 if (rc)
John Wang58a0e062019-11-08 15:38:15 +0800172 {
Thu Nguyen94270892023-10-25 17:11:44 +0700173 std::cerr << "failed to pldm send recv error rc " << rc << std::endl;
John Wang58a0e062019-11-08 15:38:15 +0800174 }
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000175
Thu Nguyen94270892023-10-25 17:11:44 +0700176 return rc;
John Wang58a0e062019-11-08 15:38:15 +0800177}
John Wang58a0e062019-11-08 15:38:15 +0800178} // namespace helper
Sampa Misraaa8ae722019-12-12 03:20:40 -0600179} // namespace pldmtool