blob: cbcf827b59d368452db8a861ef8ffbfd32c58766 [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"},
33 {PLDM_INVALID_TRANSFER_OPERATION_FLAG, "INVALID_TRANSFER_OPERATION_FLAG"}};
34
35static const std::map<uint8_t, std::string> fwupdateCompletionCodes{
36 {PLDM_FWUP_NOT_IN_UPDATE_MODE, "NOT_IN_UPDATE_MODE"},
37 {PLDM_FWUP_ALREADY_IN_UPDATE_MODE, "ALREADY_IN_UPDATE_MODE"},
38 {PLDM_FWUP_DATA_OUT_OF_RANGE, "DATA_OUT_OF_RANGE"},
39 {PLDM_FWUP_INVALID_TRANSFER_LENGTH, "INVALID_TRANSFER_LENGTH"},
40 {PLDM_FWUP_INVALID_STATE_FOR_COMMAND, "INVALID_STATE_FOR_COMMAND"},
41 {PLDM_FWUP_INCOMPLETE_UPDATE, "INCOMPLETE_UPDATE"},
42 {PLDM_FWUP_BUSY_IN_BACKGROUND, "BUSY_IN_BACKGROUND"},
43 {PLDM_FWUP_CANCEL_PENDING, "CANCEL_PENDING"},
44 {PLDM_FWUP_COMMAND_NOT_EXPECTED, "COMMAND_NOT_EXPECTED"},
45 {PLDM_FWUP_RETRY_REQUEST_FW_DATA, "RETRY_REQUEST_FW_DATA"},
46 {PLDM_FWUP_UNABLE_TO_INITIATE_UPDATE, "UNABLE_TO_INITIATE_UPDATE"},
47 {PLDM_FWUP_ACTIVATION_NOT_REQUIRED, "ACTIVATION_NOT_REQUIRED"},
48 {PLDM_FWUP_SELF_CONTAINED_ACTIVATION_NOT_PERMITTED,
49 "SELF_CONTAINED_ACTIVATION_NOT_PERMITTED"},
50 {PLDM_FWUP_NO_DEVICE_METADATA, "NO_DEVICE_METADATA"},
51 {PLDM_FWUP_RETRY_REQUEST_UPDATE, "RETRY_REQUEST_UPDATE"},
52 {PLDM_FWUP_NO_PACKAGE_DATA, "NO_PACKAGE_DATA"},
53 {PLDM_FWUP_INVALID_TRANSFER_HANDLE, "INVALID_TRANSFER_HANDLE"},
54 {PLDM_FWUP_INVALID_TRANSFER_OPERATION_FLAG,
55 "INVALID_TRANSFER_OPERATION_FLAG"},
56 {PLDM_FWUP_ACTIVATE_PENDING_IMAGE_NOT_PERMITTED,
57 "ACTIVATE_PENDING_IMAGE_NOT_PERMITTED"},
58 {PLDM_FWUP_PACKAGE_DATA_ERROR, "PACKAGE_DATA_ERROR"}};
59
60void fillCompletionCode(uint8_t completionCode, ordered_json& data,
61 uint8_t pldmType)
62{
63 // Check generic completion codes first for all PLDM types
64 auto it = genericCompletionCodes.find(completionCode);
65 if (it != genericCompletionCodes.end())
66 {
67 data["CompletionCode"] = it->second;
68 return;
69 }
70
71 // If not a generic code, check type-specific codes
72 switch (pldmType)
73 {
74 case PLDM_FWUP:
75 {
76 auto typeIt = fwupdateCompletionCodes.find(completionCode);
77 if (typeIt != fwupdateCompletionCodes.end())
78 {
79 data["CompletionCode"] = typeIt->second;
80 return;
81 }
82 break;
83 }
84 }
85
86 data["CompletionCode"] = "UNKNOWN_COMPLETION_CODE";
87}
88
John Wang58a0e062019-11-08 15:38:15 +080089void CommandInterface::exec()
90{
Dung Cao3d03f3f2023-09-07 06:51:33 +000091 instanceId = instanceIdDb.next(mctp_eid);
John Wang58a0e062019-11-08 15:38:15 +080092 auto [rc, requestMsg] = createRequestMsg();
93 if (rc != PLDM_SUCCESS)
94 {
Dung Cao3d03f3f2023-09-07 06:51:33 +000095 instanceIdDb.free(mctp_eid, instanceId);
John Wang58a0e062019-11-08 15:38:15 +080096 std::cerr << "Failed to encode request message for " << pldmType << ":"
Sampa Misraaa8ae722019-12-12 03:20:40 -060097 << commandName << " rc = " << rc << "\n";
John Wang58a0e062019-11-08 15:38:15 +080098 return;
99 }
100
John Wangb754eee2020-02-15 16:10:25 +0800101 std::vector<uint8_t> responseMsg;
102 rc = pldmSendRecv(requestMsg, responseMsg);
103
104 if (rc != PLDM_SUCCESS)
105 {
Dung Cao3d03f3f2023-09-07 06:51:33 +0000106 instanceIdDb.free(mctp_eid, instanceId);
John Wangb754eee2020-02-15 16:10:25 +0800107 std::cerr << "pldmSendRecv: Failed to receive RC = " << rc << "\n";
108 return;
109 }
110
111 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsg.data());
112 parseResponseMsg(responsePtr, responseMsg.size() - sizeof(pldm_msg_hdr));
Dung Cao3d03f3f2023-09-07 06:51:33 +0000113 instanceIdDb.free(mctp_eid, instanceId);
John Wangb754eee2020-02-15 16:10:25 +0800114}
115
116int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
117 std::vector<uint8_t>& responseMsg)
118{
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600119 // By default enable request/response msgs for pldmtool raw commands.
120 if (CommandInterface::pldmType == "raw")
121 {
122 pldmVerbose = true;
123 }
124
Tom Josephe5268cd2021-09-07 13:04:03 +0530125 if (pldmVerbose)
126 {
127 std::cout << "pldmtool: ";
128 printBuffer(Tx, requestMsg);
129 }
John Wang58a0e062019-11-08 15:38:15 +0800130
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000131 auto tid = mctp_eid;
132 PldmTransport pldmTransport{};
Thu Nguyen94270892023-10-25 17:11:44 +0700133 uint8_t retry = 0;
134 int rc = PLDM_ERROR;
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000135
Thu Nguyen94270892023-10-25 17:11:44 +0700136 while (PLDM_REQUESTER_SUCCESS != rc && retry <= numRetries)
137 {
138 void* responseMessage = nullptr;
139 size_t responseMessageSize{};
140
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400141 rc =
142 pldmTransport.sendRecvMsg(tid, requestMsg.data(), requestMsg.size(),
143 responseMessage, responseMessageSize);
Thu Nguyen94270892023-10-25 17:11:44 +0700144 if (rc)
145 {
146 std::cerr << "[" << unsigned(retry) << "] pldm_send_recv error rc "
147 << rc << std::endl;
148 retry++;
149 continue;
150 }
151
152 responseMsg.resize(responseMessageSize);
153 memcpy(responseMsg.data(), responseMessage, responseMsg.size());
154
155 free(responseMessage);
156
157 if (pldmVerbose)
158 {
159 std::cout << "pldmtool: ";
160 printBuffer(Rx, responseMsg);
161 }
162 }
163
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000164 if (rc)
John Wang58a0e062019-11-08 15:38:15 +0800165 {
Thu Nguyen94270892023-10-25 17:11:44 +0700166 std::cerr << "failed to pldm send recv error rc " << rc << std::endl;
John Wang58a0e062019-11-08 15:38:15 +0800167 }
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000168
Thu Nguyen94270892023-10-25 17:11:44 +0700169 return rc;
John Wang58a0e062019-11-08 15:38:15 +0800170}
John Wang58a0e062019-11-08 15:38:15 +0800171} // namespace helper
Sampa Misraaa8ae722019-12-12 03:20:40 -0600172} // namespace pldmtool