blob: e4885574924cc4e5edef810fd807ad5323d133db [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{
Dung Cao3d03f3f2023-09-07 06:51:33 +000092 instanceId = instanceIdDb.next(mctp_eid);
John Wang58a0e062019-11-08 15:38:15 +080093 auto [rc, requestMsg] = createRequestMsg();
94 if (rc != PLDM_SUCCESS)
95 {
Dung Cao3d03f3f2023-09-07 06:51:33 +000096 instanceIdDb.free(mctp_eid, instanceId);
John Wang58a0e062019-11-08 15:38:15 +080097 std::cerr << "Failed to encode request message for " << pldmType << ":"
Sampa Misraaa8ae722019-12-12 03:20:40 -060098 << commandName << " rc = " << rc << "\n";
John Wang58a0e062019-11-08 15:38:15 +080099 return;
100 }
101
John Wangb754eee2020-02-15 16:10:25 +0800102 std::vector<uint8_t> responseMsg;
103 rc = pldmSendRecv(requestMsg, responseMsg);
104
105 if (rc != PLDM_SUCCESS)
106 {
Dung Cao3d03f3f2023-09-07 06:51:33 +0000107 instanceIdDb.free(mctp_eid, instanceId);
John Wangb754eee2020-02-15 16:10:25 +0800108 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 Cao3d03f3f2023-09-07 06:51:33 +0000114 instanceIdDb.free(mctp_eid, instanceId);
John Wangb754eee2020-02-15 16:10:25 +0800115}
116
117int CommandInterface::pldmSendRecv(std::vector<uint8_t>& requestMsg,
118 std::vector<uint8_t>& responseMsg)
119{
Sridevi Rameshc91822b2020-02-27 09:26:41 -0600120 // By default enable request/response msgs for pldmtool raw commands.
121 if (CommandInterface::pldmType == "raw")
122 {
123 pldmVerbose = true;
124 }
125
Tom Josephe5268cd2021-09-07 13:04:03 +0530126 if (pldmVerbose)
127 {
128 std::cout << "pldmtool: ";
129 printBuffer(Tx, requestMsg);
130 }
John Wang58a0e062019-11-08 15:38:15 +0800131
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000132 auto tid = mctp_eid;
133 PldmTransport pldmTransport{};
Thu Nguyen94270892023-10-25 17:11:44 +0700134 uint8_t retry = 0;
135 int rc = PLDM_ERROR;
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000136
Thu Nguyen94270892023-10-25 17:11:44 +0700137 while (PLDM_REQUESTER_SUCCESS != rc && retry <= numRetries)
138 {
139 void* responseMessage = nullptr;
140 size_t responseMessageSize{};
141
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400142 rc =
143 pldmTransport.sendRecvMsg(tid, requestMsg.data(), requestMsg.size(),
144 responseMessage, responseMessageSize);
Thu Nguyen94270892023-10-25 17:11:44 +0700145 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 Gupta1ed5f7a2023-05-22 13:56:42 +1000165 if (rc)
John Wang58a0e062019-11-08 15:38:15 +0800166 {
Thu Nguyen94270892023-10-25 17:11:44 +0700167 std::cerr << "failed to pldm send recv error rc " << rc << std::endl;
John Wang58a0e062019-11-08 15:38:15 +0800168 }
Rashmica Gupta1ed5f7a2023-05-22 13:56:42 +1000169
Thu Nguyen94270892023-10-25 17:11:44 +0700170 return rc;
John Wang58a0e062019-11-08 15:38:15 +0800171}
John Wang58a0e062019-11-08 15:38:15 +0800172} // namespace helper
Sampa Misraaa8ae722019-12-12 03:20:40 -0600173} // namespace pldmtool