blob: c8e682e28b3364651a4ff680dff0684f626a5a5e [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
Tom Joseph96b6d812017-04-28 01:27:17 +053044 if (!std::get<sol::Manager&>(singletonPool).enable)
45 {
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 Maueryae1fda42018-10-15 12:55:34 -070057 auto session = std::get<session::Manager&>(singletonPool)
58 .getSession(handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053059
60 if (!request->encryption && session->isCryptAlgoEnabled())
61 {
62 response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
63 return outPayload;
64 }
65
Saravanan Palanisamy0a269042019-07-05 02:21:21 +000066 // Is SOL Payload enabled for this user & channel.
67 auto userId = ipmi::ipmiUserGetUserId(session->userName);
68 ipmi::PayloadAccess payloadAccess = {};
69 if ((ipmi::ipmiUserGetUserPayloadAccess(session->channelNum(), userId,
70 payloadAccess) != IPMI_CC_OK) ||
71 !(payloadAccess.stdPayloadEnables1[static_cast<uint8_t>(
72 message::PayloadType::SOL)]))
73 {
74 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
75 return outPayload;
76 }
77
Vernon Mauery9e801a22018-10-12 13:20:49 -070078 auto status = std::get<sol::Manager&>(singletonPool)
79 .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 Mauery9e801a22018-10-12 13:20:49 -070092 std::get<sol::Manager&>(singletonPool)
93 .startPayloadInstance(request->payloadInstance, 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 Mauery9e801a22018-10-12 13:20:49 -0700142 auto status = std::get<sol::Manager&>(singletonPool)
143 .isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530144 if (!status)
145 {
146 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
147 return outPayload;
148 }
149
150 try
151 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700152 auto& context = std::get<sol::Manager&>(singletonPool)
153 .getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530154 auto sessionID = context.sessionID;
155
Vernon Mauery9e801a22018-10-12 13:20:49 -0700156 std::get<sol::Manager&>(singletonPool)
157 .stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530158
Tom Joseph6516cef2017-07-31 18:48:34 +0530159 try
160 {
161 activating(request->payloadInstance, sessionID);
162 }
163 catch (std::exception& e)
164 {
165 log<level::INFO>(e.what());
166 /*
167 * In case session has been closed (like in the case of inactivity
168 * timeout), then activating function would throw an exception,
169 * since sessionID is not found. IPMI success completion code is
170 * returned, since the session is closed.
171 */
172 return outPayload;
173 }
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530174 }
175 catch (std::exception& e)
176 {
177 log<level::ERR>(e.what());
178 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
179 return outPayload;
180 }
181
182 return outPayload;
183}
184
Tom Joseph18a45e92017-04-11 11:30:44 +0530185std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530186 const message::Handler& handler)
187{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700188 auto request =
189 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700190 if (inPayload.size() != sizeof(*request))
191 {
192 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
193 return errorPayload;
194 }
195
196 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700197 auto response =
198 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530199
200 // SOL is the payload currently supported for payload status
201 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
202 {
203 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
204 return outPayload;
205 }
206
207 response->completionCode = IPMI_CC_OK;
Ayushi Smritiddba9d12019-09-13 12:03:31 +0530208
209 constexpr size_t maxSolPayloadInstances = 1;
210 response->capacity = maxSolPayloadInstances;
Tom Josephe1ae56c2017-04-03 02:03:41 +0530211
212 // Currently we support only one SOL session
213 response->instance1 =
Vernon Mauery9e801a22018-10-12 13:20:49 -0700214 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530215
216 return outPayload;
217}
218
Tom Joseph80938492018-03-22 10:05:20 +0530219std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
220 const message::Handler& handler)
221{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700222 auto request =
223 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700224
225 if (inPayload.size() != sizeof(*request))
226 {
227 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
228 return errorPayload;
229 }
230
231 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700232 auto response =
233 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530234
235 // SOL is the payload currently supported for payload status & only one
236 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700237 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
238 request->payloadType ||
239 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530240 {
241 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
242 return outPayload;
243 }
Vernon Mauery9e801a22018-10-12 13:20:49 -0700244 auto status = std::get<sol::Manager&>(singletonPool)
245 .isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530246
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530247 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530248 {
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530249 auto& context = std::get<sol::Manager&>(singletonPool)
250 .getContext(request->payloadInstance);
251 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530252 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530253 else
254 {
255 // No active payload - return session id as 0
256 response->sessionID = 0;
257 }
258 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530259 return outPayload;
260}
261
Tom Joseph5c846a82017-04-03 01:59:39 +0530262} // namespace command
263
264} // namespace sol