blob: bc987c5dec395f4de4cd798c92e8a4e508d9d194 [file] [log] [blame]
Tom Joseph5c846a82017-04-03 01:59:39 +05301#include "payload_cmds.hpp"
Vernon Mauery9e801a22018-10-12 13:20:49 -07002
3#include "main.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
Cheng C Yang29086952020-03-09 15:29:18 +080044 std::get<sol::Manager&>(singletonPool)
45 .updateSOLParameter(ipmi::convertCurrentChannelNum(
46 ipmi::currentChNum, getInterfaceIndex()));
Tom Joseph96b6d812017-04-28 01:27:17 +053047 if (!std::get<sol::Manager&>(singletonPool).enable)
48 {
49 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
50 return outPayload;
51 }
52
Tom Joseph5c846a82017-04-03 01:59:39 +053053 // Only one instance of SOL is currently supported.
54 if (request->payloadInstance != 1)
55 {
56 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
57 return outPayload;
58 }
59
Vernon Maueryae1fda42018-10-15 12:55:34 -070060 auto session = std::get<session::Manager&>(singletonPool)
61 .getSession(handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053062
63 if (!request->encryption && session->isCryptAlgoEnabled())
64 {
65 response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
66 return outPayload;
67 }
68
Saravanan Palanisamy0a269042019-07-05 02:21:21 +000069 // Is SOL Payload enabled for this user & channel.
70 auto userId = ipmi::ipmiUserGetUserId(session->userName);
71 ipmi::PayloadAccess payloadAccess = {};
72 if ((ipmi::ipmiUserGetUserPayloadAccess(session->channelNum(), userId,
73 payloadAccess) != IPMI_CC_OK) ||
74 !(payloadAccess.stdPayloadEnables1[static_cast<uint8_t>(
75 message::PayloadType::SOL)]))
76 {
77 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
78 return outPayload;
79 }
80
Vernon Mauery9e801a22018-10-12 13:20:49 -070081 auto status = std::get<sol::Manager&>(singletonPool)
82 .isPayloadActive(request->payloadInstance);
Tom Joseph5c846a82017-04-03 01:59:39 +053083 if (status)
84 {
85 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
86 return outPayload;
87 }
88
89 // Set the current command's socket channel to the session
90 handler.setChannelInSession();
91
92 // Start the SOL payload
93 try
94 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070095 std::get<sol::Manager&>(singletonPool)
96 .startPayloadInstance(request->payloadInstance, handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053097 }
98 catch (std::exception& e)
99 {
100 log<level::ERR>(e.what());
101 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
102 return outPayload;
103 }
104
105 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
106 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
107 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
108
109 // VLAN addressing is not used
110 response->vlanNum = 0xFFFF;
111
112 return outPayload;
113}
114
Tom Joseph18a45e92017-04-11 11:30:44 +0530115std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530116 const message::Handler& handler)
117{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700118 auto request =
119 reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700120 if (inPayload.size() != sizeof(*request))
121 {
122 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
123 return errorPayload;
124 }
125
126 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700127 auto response =
128 reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530129 response->completionCode = IPMI_CC_OK;
130
131 // SOL is the payload currently supported for deactivation
132 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
133 {
134 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
135 return outPayload;
136 }
137
138 // Only one instance of SOL is supported
139 if (request->payloadInstance != 1)
140 {
141 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
142 return outPayload;
143 }
144
Vernon Mauery9e801a22018-10-12 13:20:49 -0700145 auto status = std::get<sol::Manager&>(singletonPool)
146 .isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530147 if (!status)
148 {
149 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
150 return outPayload;
151 }
152
153 try
154 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700155 auto& context = std::get<sol::Manager&>(singletonPool)
156 .getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530157 auto sessionID = context.sessionID;
158
Vernon Mauery9e801a22018-10-12 13:20:49 -0700159 std::get<sol::Manager&>(singletonPool)
160 .stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530161
Tom Joseph6516cef2017-07-31 18:48:34 +0530162 try
163 {
164 activating(request->payloadInstance, sessionID);
165 }
166 catch (std::exception& e)
167 {
168 log<level::INFO>(e.what());
169 /*
170 * In case session has been closed (like in the case of inactivity
171 * timeout), then activating function would throw an exception,
172 * since sessionID is not found. IPMI success completion code is
173 * returned, since the session is closed.
174 */
175 return outPayload;
176 }
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530177 }
178 catch (std::exception& e)
179 {
180 log<level::ERR>(e.what());
181 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
182 return outPayload;
183 }
184
185 return outPayload;
186}
187
Tom Joseph18a45e92017-04-11 11:30:44 +0530188std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530189 const message::Handler& handler)
190{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700191 auto request =
192 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700193 if (inPayload.size() != sizeof(*request))
194 {
195 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
196 return errorPayload;
197 }
198
199 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700200 auto response =
201 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530202
203 // SOL is the payload currently supported for payload status
204 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
205 {
206 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
207 return outPayload;
208 }
209
210 response->completionCode = IPMI_CC_OK;
Ayushi Smritiddba9d12019-09-13 12:03:31 +0530211
212 constexpr size_t maxSolPayloadInstances = 1;
213 response->capacity = maxSolPayloadInstances;
Tom Josephe1ae56c2017-04-03 02:03:41 +0530214
215 // Currently we support only one SOL session
216 response->instance1 =
Vernon Mauery9e801a22018-10-12 13:20:49 -0700217 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530218
219 return outPayload;
220}
221
Tom Joseph80938492018-03-22 10:05:20 +0530222std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
223 const message::Handler& handler)
224{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700225 auto request =
226 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700227
228 if (inPayload.size() != sizeof(*request))
229 {
230 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
231 return errorPayload;
232 }
233
234 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700235 auto response =
236 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530237
238 // SOL is the payload currently supported for payload status & only one
239 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700240 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
241 request->payloadType ||
242 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530243 {
244 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
245 return outPayload;
246 }
Vernon Mauery9e801a22018-10-12 13:20:49 -0700247 auto status = std::get<sol::Manager&>(singletonPool)
248 .isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530249
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530250 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530251 {
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530252 auto& context = std::get<sol::Manager&>(singletonPool)
253 .getContext(request->payloadInstance);
254 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530255 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530256 else
257 {
258 // No active payload - return session id as 0
259 response->sessionID = 0;
260 }
261 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530262 return outPayload;
263}
264
Tom Joseph5c846a82017-04-03 01:59:39 +0530265} // namespace command
266
267} // namespace sol