blob: ecb86e7dae946e2725772f91b6ae9646d3069fe5 [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>
Vernon Mauery9e801a22018-10-12 13:20:49 -070010#include <phosphor-logging/log.hpp>
11
Tom Joseph5c846a82017-04-03 01:59:39 +053012namespace sol
13{
14
15namespace command
16{
17
18using namespace phosphor::logging;
19
Tom Joseph18a45e92017-04-11 11:30:44 +053020std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload,
Tom Joseph5c846a82017-04-03 01:59:39 +053021 const message::Handler& handler)
22{
Vernon Mauery9e801a22018-10-12 13:20:49 -070023 auto request =
24 reinterpret_cast<const ActivatePayloadRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -070025 if (inPayload.size() != sizeof(*request))
26 {
27 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
28 return errorPayload;
29 }
30
31 std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -070032 auto response =
33 reinterpret_cast<ActivatePayloadResponse*>(outPayload.data());
Tom Joseph5c846a82017-04-03 01:59:39 +053034
35 response->completionCode = IPMI_CC_OK;
36
37 // SOL is the payload currently supported for activation.
38 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
39 {
40 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
41 return outPayload;
42 }
43
Vernon Mauery2085ae02021-06-10 11:51:00 -070044 sol::Manager::get().updateSOLParameter(ipmi::convertCurrentChannelNum(
45 ipmi::currentChNum, getInterfaceIndex()));
46 if (!sol::Manager::get().enable)
Tom Joseph96b6d812017-04-28 01:27:17 +053047 {
48 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
49 return outPayload;
50 }
51
Tom Joseph5c846a82017-04-03 01:59:39 +053052 // Only one instance of SOL is currently supported.
53 if (request->payloadInstance != 1)
54 {
55 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
56 return outPayload;
57 }
58
Vernon Mauery2085ae02021-06-10 11:51:00 -070059 auto session = session::Manager::get().getSession(handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053060
61 if (!request->encryption && session->isCryptAlgoEnabled())
62 {
63 response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
64 return outPayload;
65 }
66
Saravanan Palanisamy0a269042019-07-05 02:21:21 +000067 // Is SOL Payload enabled for this user & channel.
68 auto userId = ipmi::ipmiUserGetUserId(session->userName);
69 ipmi::PayloadAccess payloadAccess = {};
70 if ((ipmi::ipmiUserGetUserPayloadAccess(session->channelNum(), userId,
71 payloadAccess) != IPMI_CC_OK) ||
72 !(payloadAccess.stdPayloadEnables1[static_cast<uint8_t>(
73 message::PayloadType::SOL)]))
74 {
75 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
76 return outPayload;
77 }
78
Vernon Mauery2085ae02021-06-10 11:51:00 -070079 auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
Tom Joseph5c846a82017-04-03 01:59:39 +053080 if (status)
81 {
82 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
83 return outPayload;
84 }
85
86 // Set the current command's socket channel to the session
87 handler.setChannelInSession();
88
89 // Start the SOL payload
90 try
91 {
Vernon Mauery2085ae02021-06-10 11:51:00 -070092 sol::Manager::get().startPayloadInstance(request->payloadInstance,
93 handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053094 }
95 catch (std::exception& e)
96 {
97 log<level::ERR>(e.what());
98 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
99 return outPayload;
100 }
101
102 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
103 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
104 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
105
106 // VLAN addressing is not used
107 response->vlanNum = 0xFFFF;
108
109 return outPayload;
110}
111
Tom Joseph18a45e92017-04-11 11:30:44 +0530112std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530113 const message::Handler& handler)
114{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700115 auto request =
116 reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700117 if (inPayload.size() != sizeof(*request))
118 {
119 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
120 return errorPayload;
121 }
122
123 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700124 auto response =
125 reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530126 response->completionCode = IPMI_CC_OK;
127
128 // SOL is the payload currently supported for deactivation
129 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
130 {
131 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
132 return outPayload;
133 }
134
135 // Only one instance of SOL is supported
136 if (request->payloadInstance != 1)
137 {
138 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
139 return outPayload;
140 }
141
Vernon Mauery2085ae02021-06-10 11:51:00 -0700142 auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530143 if (!status)
144 {
145 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
146 return outPayload;
147 }
148
149 try
150 {
Vernon Mauery2085ae02021-06-10 11:51:00 -0700151 auto& context =
152 sol::Manager::get().getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530153 auto sessionID = context.sessionID;
154
Vernon Mauery2085ae02021-06-10 11:51:00 -0700155 sol::Manager::get().stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530156
Tom Joseph6516cef2017-07-31 18:48:34 +0530157 try
158 {
159 activating(request->payloadInstance, sessionID);
160 }
161 catch (std::exception& e)
162 {
163 log<level::INFO>(e.what());
164 /*
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 }
173 catch (std::exception& e)
174 {
175 log<level::ERR>(e.what());
176 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
177 return outPayload;
178 }
179
180 return outPayload;
181}
182
Tom Joseph18a45e92017-04-11 11:30:44 +0530183std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530184 const message::Handler& handler)
185{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700186 auto request =
187 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700188 if (inPayload.size() != sizeof(*request))
189 {
190 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
191 return errorPayload;
192 }
193
194 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700195 auto response =
196 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530197
198 // SOL is the payload currently supported for payload status
199 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
200 {
201 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
202 return outPayload;
203 }
204
205 response->completionCode = IPMI_CC_OK;
Ayushi Smritiddba9d12019-09-13 12:03:31 +0530206
207 constexpr size_t maxSolPayloadInstances = 1;
208 response->capacity = maxSolPayloadInstances;
Tom Josephe1ae56c2017-04-03 02:03:41 +0530209
210 // Currently we support only one SOL session
Vernon Mauery2085ae02021-06-10 11:51:00 -0700211 response->instance1 = sol::Manager::get().isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530212
213 return outPayload;
214}
215
Tom Joseph80938492018-03-22 10:05:20 +0530216std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
217 const message::Handler& handler)
218{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700219 auto request =
220 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700221
222 if (inPayload.size() != sizeof(*request))
223 {
224 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
225 return errorPayload;
226 }
227
228 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700229 auto response =
230 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530231
232 // SOL is the payload currently supported for payload status & only one
233 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700234 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
235 request->payloadType ||
236 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530237 {
238 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
239 return outPayload;
240 }
Vernon Mauery2085ae02021-06-10 11:51:00 -0700241 auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530242
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530243 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530244 {
Vernon Mauery2085ae02021-06-10 11:51:00 -0700245 auto& context =
246 sol::Manager::get().getContext(request->payloadInstance);
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530247 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530248 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530249 else
250 {
251 // No active payload - return session id as 0
252 response->sessionID = 0;
253 }
254 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530255 return outPayload;
256}
257
Tom Joseph5c846a82017-04-03 01:59:39 +0530258} // namespace command
259
260} // namespace sol