blob: c5d64fb3e27c7ca2618b680d28075d4b8e6909c1 [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 }
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530176 }
177 catch (std::exception& e)
178 {
179 log<level::ERR>(e.what());
180 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
181 return outPayload;
182 }
183
184 return outPayload;
185}
186
Tom Joseph18a45e92017-04-11 11:30:44 +0530187std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530188 const message::Handler& handler)
189{
190 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700191 auto request =
192 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
193 auto response =
194 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530195
196 // SOL is the payload currently supported for payload status
197 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
198 {
199 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
200 return outPayload;
201 }
202
203 response->completionCode = IPMI_CC_OK;
Ayushi Smritiddba9d12019-09-13 12:03:31 +0530204
205 constexpr size_t maxSolPayloadInstances = 1;
206 response->capacity = maxSolPayloadInstances;
Tom Josephe1ae56c2017-04-03 02:03:41 +0530207
208 // Currently we support only one SOL session
209 response->instance1 =
Vernon Mauery9e801a22018-10-12 13:20:49 -0700210 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530211
212 return outPayload;
213}
214
Tom Joseph80938492018-03-22 10:05:20 +0530215std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
216 const message::Handler& handler)
217{
218 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700219 auto request =
220 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
221 auto response =
222 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530223
anil kumar appana35ca1502019-07-04 15:00:29 +0000224 if (inPayload.size() != sizeof(GetPayloadInfoRequest))
225 {
226 response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
227 return outPayload;
228 }
Tom Joseph80938492018-03-22 10:05:20 +0530229 // SOL is the payload currently supported for payload status & only one
230 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700231 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
232 request->payloadType ||
233 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530234 {
235 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
236 return outPayload;
237 }
Vernon Mauery9e801a22018-10-12 13:20:49 -0700238 auto status = std::get<sol::Manager&>(singletonPool)
239 .isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530240
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530241 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530242 {
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530243 auto& context = std::get<sol::Manager&>(singletonPool)
244 .getContext(request->payloadInstance);
245 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530246 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530247 else
248 {
249 // No active payload - return session id as 0
250 response->sessionID = 0;
251 }
252 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530253 return outPayload;
254}
255
Tom Joseph5c846a82017-04-03 01:59:39 +0530256} // namespace command
257
258} // namespace sol