blob: 8f573a886a375b284de511f9ca1f7c5fd2ea50e9 [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{
23 std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -070024 auto request =
25 reinterpret_cast<const ActivatePayloadRequest*>(inPayload.data());
26 auto response =
27 reinterpret_cast<ActivatePayloadResponse*>(outPayload.data());
Tom Joseph5c846a82017-04-03 01:59:39 +053028
Ayushi Smritib12d8752019-09-18 18:37:09 +053029 if (inPayload.size() != sizeof(ActivatePayloadRequest))
30 {
31 response->completionCode = ipmi::ccReqDataLenInvalid;
32 outPayload.resize(sizeof(response->completionCode));
33 return outPayload;
34 }
35
Tom Joseph5c846a82017-04-03 01:59:39 +053036 response->completionCode = IPMI_CC_OK;
37
38 // SOL is the payload currently supported for activation.
39 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
40 {
41 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
42 return outPayload;
43 }
44
Tom Joseph96b6d812017-04-28 01:27:17 +053045 if (!std::get<sol::Manager&>(singletonPool).enable)
46 {
47 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
48 return outPayload;
49 }
50
Tom Joseph5c846a82017-04-03 01:59:39 +053051 // Only one instance of SOL is currently supported.
52 if (request->payloadInstance != 1)
53 {
54 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
55 return outPayload;
56 }
57
Vernon Maueryae1fda42018-10-15 12:55:34 -070058 auto session = std::get<session::Manager&>(singletonPool)
59 .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 Mauery9e801a22018-10-12 13:20:49 -070079 auto status = std::get<sol::Manager&>(singletonPool)
80 .isPayloadActive(request->payloadInstance);
Tom Joseph5c846a82017-04-03 01:59:39 +053081 if (status)
82 {
83 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
84 return outPayload;
85 }
86
87 // Set the current command's socket channel to the session
88 handler.setChannelInSession();
89
90 // Start the SOL payload
91 try
92 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070093 std::get<sol::Manager&>(singletonPool)
94 .startPayloadInstance(request->payloadInstance, handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053095 }
96 catch (std::exception& e)
97 {
98 log<level::ERR>(e.what());
99 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
100 return outPayload;
101 }
102
103 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
104 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
105 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
106
107 // VLAN addressing is not used
108 response->vlanNum = 0xFFFF;
109
110 return outPayload;
111}
112
Tom Joseph18a45e92017-04-11 11:30:44 +0530113std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530114 const message::Handler& handler)
115{
116 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700117 auto request =
118 reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
119 auto response =
120 reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530121
122 response->completionCode = IPMI_CC_OK;
123
Sumanth Bhatb9631f82019-03-07 11:51:53 +0530124 if (inPayload.size() != sizeof(DeactivatePayloadRequest))
125 {
126 response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
127 return outPayload;
128 }
129
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530130 // SOL is the payload currently supported for deactivation
131 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
132 {
133 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
134 return outPayload;
135 }
136
137 // Only one instance of SOL is supported
138 if (request->payloadInstance != 1)
139 {
140 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
141 return outPayload;
142 }
143
Vernon Mauery9e801a22018-10-12 13:20:49 -0700144 auto status = std::get<sol::Manager&>(singletonPool)
145 .isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530146 if (!status)
147 {
148 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
149 return outPayload;
150 }
151
152 try
153 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700154 auto& context = std::get<sol::Manager&>(singletonPool)
155 .getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530156 auto sessionID = context.sessionID;
157
Vernon Mauery9e801a22018-10-12 13:20:49 -0700158 std::get<sol::Manager&>(singletonPool)
159 .stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530160
Tom Joseph6516cef2017-07-31 18:48:34 +0530161 try
162 {
163 activating(request->payloadInstance, sessionID);
164 }
165 catch (std::exception& e)
166 {
167 log<level::INFO>(e.what());
168 /*
169 * In case session has been closed (like in the case of inactivity
170 * timeout), then activating function would throw an exception,
171 * since sessionID is not found. IPMI success completion code is
172 * returned, since the session is closed.
173 */
174 return outPayload;
175 }
176
Vernon Mauery9e801a22018-10-12 13:20:49 -0700177 auto check =
178 std::get<session::Manager&>(singletonPool).stopSession(sessionID);
Tom Joseph6516cef2017-07-31 18:48:34 +0530179 if (!check)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530180 {
181 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
182 }
183 }
184 catch (std::exception& e)
185 {
186 log<level::ERR>(e.what());
187 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
188 return outPayload;
189 }
190
191 return outPayload;
192}
193
Tom Joseph18a45e92017-04-11 11:30:44 +0530194std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530195 const message::Handler& handler)
196{
197 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700198 auto request =
199 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
200 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;
211 response->capacity = MAX_PAYLOAD_INSTANCES;
212
213 // Currently we support only one SOL session
214 response->instance1 =
Vernon Mauery9e801a22018-10-12 13:20:49 -0700215 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530216
217 return outPayload;
218}
219
Tom Joseph80938492018-03-22 10:05:20 +0530220std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
221 const message::Handler& handler)
222{
223 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700224 auto request =
225 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
226 auto response =
227 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530228
anil kumar appana35ca1502019-07-04 15:00:29 +0000229 if (inPayload.size() != sizeof(GetPayloadInfoRequest))
230 {
231 response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
232 return outPayload;
233 }
Tom Joseph80938492018-03-22 10:05:20 +0530234 // 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 Mauery9e801a22018-10-12 13:20:49 -0700243 auto status = std::get<sol::Manager&>(singletonPool)
244 .isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530245
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530246 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530247 {
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530248 auto& context = std::get<sol::Manager&>(singletonPool)
249 .getContext(request->payloadInstance);
250 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530251 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530252 else
253 {
254 // No active payload - return session id as 0
255 response->sessionID = 0;
256 }
257 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530258 return outPayload;
259}
260
Tom Joseph5c846a82017-04-03 01:59:39 +0530261} // namespace command
262
263} // namespace sol