blob: b3bcca21370584cb96fc46578c90ac474eba3d62 [file] [log] [blame]
Tom Joseph5c846a82017-04-03 01:59:39 +05301#include "payload_cmds.hpp"
Vernon Mauery9e801a22018-10-12 13:20:49 -07002
Vernon Mauery2085ae02021-06-10 11:51:00 -07003#include "sessions_manager.hpp"
Tom Joseph5c846a82017-04-03 01:59:39 +05304#include "sol/sol_manager.hpp"
5#include "sol_cmds.hpp"
6
William A. Kennington III4f09eae2019-02-12 17:10:35 -08007#include <ipmid/api.h>
Vernon Mauery9e801a22018-10-12 13:20:49 -07008
Ayushi Smritib12d8752019-09-18 18:37:09 +05309#include <ipmid/api-types.hpp>
George Liu7b7f25f2022-07-04 17:07:32 +080010#include <phosphor-logging/lg2.hpp>
Vernon Mauery9e801a22018-10-12 13:20:49 -070011
Tom Joseph5c846a82017-04-03 01:59:39 +053012namespace sol
13{
14
15namespace command
16{
17
Tom Joseph18a45e92017-04-11 11:30:44 +053018std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload,
Vernon Mauery41ff9b52021-06-11 11:37:40 -070019 std::shared_ptr<message::Handler>& handler)
Tom Joseph5c846a82017-04-03 01:59:39 +053020{
Vernon Mauery9e801a22018-10-12 13:20:49 -070021 auto request =
22 reinterpret_cast<const ActivatePayloadRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -070023 if (inPayload.size() != sizeof(*request))
24 {
25 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
26 return errorPayload;
27 }
28
29 std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -070030 auto response =
31 reinterpret_cast<ActivatePayloadResponse*>(outPayload.data());
Tom Joseph5c846a82017-04-03 01:59:39 +053032
33 response->completionCode = IPMI_CC_OK;
34
35 // SOL is the payload currently supported for activation.
36 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
37 {
38 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
39 return outPayload;
40 }
41
Vernon Mauery2085ae02021-06-10 11:51:00 -070042 sol::Manager::get().updateSOLParameter(ipmi::convertCurrentChannelNum(
43 ipmi::currentChNum, getInterfaceIndex()));
44 if (!sol::Manager::get().enable)
Tom Joseph96b6d812017-04-28 01:27:17 +053045 {
46 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
47 return outPayload;
48 }
49
Tom Joseph5c846a82017-04-03 01:59:39 +053050 // Only one instance of SOL is currently supported.
51 if (request->payloadInstance != 1)
52 {
53 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
54 return outPayload;
55 }
56
Vernon Mauery41ff9b52021-06-11 11:37:40 -070057 auto session = session::Manager::get().getSession(handler->sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053058
59 if (!request->encryption && session->isCryptAlgoEnabled())
60 {
61 response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
62 return outPayload;
63 }
64
Saravanan Palanisamy0a269042019-07-05 02:21:21 +000065 // Is SOL Payload enabled for this user & channel.
66 auto userId = ipmi::ipmiUserGetUserId(session->userName);
67 ipmi::PayloadAccess payloadAccess = {};
68 if ((ipmi::ipmiUserGetUserPayloadAccess(session->channelNum(), userId,
69 payloadAccess) != IPMI_CC_OK) ||
70 !(payloadAccess.stdPayloadEnables1[static_cast<uint8_t>(
71 message::PayloadType::SOL)]))
72 {
73 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
74 return outPayload;
75 }
76
Vernon Mauery2085ae02021-06-10 11:51:00 -070077 auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
Tom Joseph5c846a82017-04-03 01:59:39 +053078 if (status)
79 {
80 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
81 return outPayload;
82 }
83
84 // Set the current command's socket channel to the session
Vernon Mauery41ff9b52021-06-11 11:37:40 -070085 handler->setChannelInSession();
Tom Joseph5c846a82017-04-03 01:59:39 +053086
87 // Start the SOL payload
88 try
89 {
Vernon Mauery2085ae02021-06-10 11:51:00 -070090 sol::Manager::get().startPayloadInstance(request->payloadInstance,
Vernon Mauery41ff9b52021-06-11 11:37:40 -070091 handler->sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053092 }
Patrick Williams12d199b2021-10-06 12:36:48 -050093 catch (const std::exception& e)
Tom Joseph5c846a82017-04-03 01:59:39 +053094 {
George Liu7b7f25f2022-07-04 17:07:32 +080095 lg2::error("Failed to start SOL payload: {ERROR}", "ERROR", e);
Tom Joseph5c846a82017-04-03 01:59:39 +053096 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
97 return outPayload;
98 }
99
100 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
101 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
102 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
103
104 // VLAN addressing is not used
105 response->vlanNum = 0xFFFF;
106
107 return outPayload;
108}
109
Vernon Mauery41ff9b52021-06-11 11:37:40 -0700110std::vector<uint8_t>
111 deactivatePayload(const std::vector<uint8_t>& inPayload,
George Liube1470c2022-07-04 14:33:24 +0800112 std::shared_ptr<message::Handler>& /* handler */)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530113{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700114 auto request =
115 reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700116 if (inPayload.size() != sizeof(*request))
117 {
118 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
119 return errorPayload;
120 }
121
122 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700123 auto response =
124 reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530125 response->completionCode = IPMI_CC_OK;
126
127 // SOL is the payload currently supported for deactivation
128 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
129 {
130 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
131 return outPayload;
132 }
133
134 // Only one instance of SOL is supported
135 if (request->payloadInstance != 1)
136 {
137 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
138 return outPayload;
139 }
140
Vernon Mauery2085ae02021-06-10 11:51:00 -0700141 auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530142 if (!status)
143 {
144 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
145 return outPayload;
146 }
147
148 try
149 {
Vernon Mauery2085ae02021-06-10 11:51:00 -0700150 auto& context =
151 sol::Manager::get().getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530152 auto sessionID = context.sessionID;
153
Vernon Mauery2085ae02021-06-10 11:51:00 -0700154 sol::Manager::get().stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530155
Tom Joseph6516cef2017-07-31 18:48:34 +0530156 try
157 {
158 activating(request->payloadInstance, sessionID);
159 }
Patrick Williams12d199b2021-10-06 12:36:48 -0500160 catch (const std::exception& e)
Tom Joseph6516cef2017-07-31 18:48:34 +0530161 {
George Liu7b7f25f2022-07-04 17:07:32 +0800162 lg2::info("Failed to call the activating method: {ERROR}", "ERROR",
163 e);
Tom Joseph6516cef2017-07-31 18:48:34 +0530164 /*
165 * In case session has been closed (like in the case of inactivity
166 * timeout), then activating function would throw an exception,
167 * since sessionID is not found. IPMI success completion code is
168 * returned, since the session is closed.
169 */
170 return outPayload;
171 }
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530172 }
Patrick Williams12d199b2021-10-06 12:36:48 -0500173 catch (const std::exception& e)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530174 {
George Liu7b7f25f2022-07-04 17:07:32 +0800175 lg2::error("Failed to call the getContext method: {ERROR}", "ERROR", e);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530176 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
177 return outPayload;
178 }
179
180 return outPayload;
181}
182
Vernon Mauery41ff9b52021-06-11 11:37:40 -0700183std::vector<uint8_t>
184 getPayloadStatus(const std::vector<uint8_t>& inPayload,
George Liube1470c2022-07-04 14:33:24 +0800185 std::shared_ptr<message::Handler>& /* handler */)
Tom Josephe1ae56c2017-04-03 02:03:41 +0530186{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700187 auto request =
188 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700189 if (inPayload.size() != sizeof(*request))
190 {
191 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
192 return errorPayload;
193 }
194
195 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700196 auto response =
197 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530198
199 // SOL is the payload currently supported for payload status
200 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
201 {
202 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
203 return outPayload;
204 }
205
206 response->completionCode = IPMI_CC_OK;
Ayushi Smritiddba9d12019-09-13 12:03:31 +0530207
208 constexpr size_t maxSolPayloadInstances = 1;
209 response->capacity = maxSolPayloadInstances;
Tom Josephe1ae56c2017-04-03 02:03:41 +0530210
211 // Currently we support only one SOL session
Vernon Mauery2085ae02021-06-10 11:51:00 -0700212 response->instance1 = sol::Manager::get().isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530213
214 return outPayload;
215}
216
George Liube1470c2022-07-04 14:33:24 +0800217std::vector<uint8_t>
218 getPayloadInfo(const std::vector<uint8_t>& inPayload,
219 std::shared_ptr<message::Handler>& /* handler */)
Tom Joseph80938492018-03-22 10:05:20 +0530220{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700221 auto request =
222 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700223
224 if (inPayload.size() != sizeof(*request))
225 {
226 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
227 return errorPayload;
228 }
229
230 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700231 auto response =
232 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530233
234 // SOL is the payload currently supported for payload status & only one
235 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700236 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
237 request->payloadType ||
238 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530239 {
240 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
241 return outPayload;
242 }
Vernon Mauery2085ae02021-06-10 11:51:00 -0700243 auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530244
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530245 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530246 {
Vernon Mauery2085ae02021-06-10 11:51:00 -0700247 auto& context =
248 sol::Manager::get().getContext(request->payloadInstance);
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530249 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530250 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530251 else
252 {
253 // No active payload - return session id as 0
254 response->sessionID = 0;
255 }
256 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530257 return outPayload;
258}
259
Tom Joseph5c846a82017-04-03 01:59:39 +0530260} // namespace command
261
262} // namespace sol