blob: fb207ac8d420cc8e039d6525891ae2feebb89f21 [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
9#include <phosphor-logging/log.hpp>
10
Tom Joseph5c846a82017-04-03 01:59:39 +053011namespace sol
12{
13
14namespace command
15{
16
17using namespace phosphor::logging;
18
Tom Joseph18a45e92017-04-11 11:30:44 +053019std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload,
Tom Joseph5c846a82017-04-03 01:59:39 +053020 const message::Handler& handler)
21{
22 std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -070023 auto request =
24 reinterpret_cast<const ActivatePayloadRequest*>(inPayload.data());
25 auto response =
26 reinterpret_cast<ActivatePayloadResponse*>(outPayload.data());
Tom Joseph5c846a82017-04-03 01:59:39 +053027
28 response->completionCode = IPMI_CC_OK;
29
30 // SOL is the payload currently supported for activation.
31 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
32 {
33 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
34 return outPayload;
35 }
36
Tom Joseph96b6d812017-04-28 01:27:17 +053037 if (!std::get<sol::Manager&>(singletonPool).enable)
38 {
39 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
40 return outPayload;
41 }
42
Tom Joseph5c846a82017-04-03 01:59:39 +053043 // Only one instance of SOL is currently supported.
44 if (request->payloadInstance != 1)
45 {
46 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
47 return outPayload;
48 }
49
Vernon Maueryae1fda42018-10-15 12:55:34 -070050 auto session = std::get<session::Manager&>(singletonPool)
51 .getSession(handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053052
53 if (!request->encryption && session->isCryptAlgoEnabled())
54 {
55 response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
56 return outPayload;
57 }
58
Saravanan Palanisamy0a269042019-07-05 02:21:21 +000059 // Is SOL Payload enabled for this user & channel.
60 auto userId = ipmi::ipmiUserGetUserId(session->userName);
61 ipmi::PayloadAccess payloadAccess = {};
62 if ((ipmi::ipmiUserGetUserPayloadAccess(session->channelNum(), userId,
63 payloadAccess) != IPMI_CC_OK) ||
64 !(payloadAccess.stdPayloadEnables1[static_cast<uint8_t>(
65 message::PayloadType::SOL)]))
66 {
67 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
68 return outPayload;
69 }
70
Vernon Mauery9e801a22018-10-12 13:20:49 -070071 auto status = std::get<sol::Manager&>(singletonPool)
72 .isPayloadActive(request->payloadInstance);
Tom Joseph5c846a82017-04-03 01:59:39 +053073 if (status)
74 {
75 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
76 return outPayload;
77 }
78
79 // Set the current command's socket channel to the session
80 handler.setChannelInSession();
81
82 // Start the SOL payload
83 try
84 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070085 std::get<sol::Manager&>(singletonPool)
86 .startPayloadInstance(request->payloadInstance, handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053087 }
88 catch (std::exception& e)
89 {
90 log<level::ERR>(e.what());
91 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
92 return outPayload;
93 }
94
95 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
96 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
97 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
98
99 // VLAN addressing is not used
100 response->vlanNum = 0xFFFF;
101
102 return outPayload;
103}
104
Tom Joseph18a45e92017-04-11 11:30:44 +0530105std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530106 const message::Handler& handler)
107{
108 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700109 auto request =
110 reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
111 auto response =
112 reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530113
114 response->completionCode = IPMI_CC_OK;
115
Sumanth Bhatb9631f82019-03-07 11:51:53 +0530116 if (inPayload.size() != sizeof(DeactivatePayloadRequest))
117 {
118 response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
119 return outPayload;
120 }
121
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530122 // SOL is the payload currently supported for deactivation
123 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
124 {
125 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
126 return outPayload;
127 }
128
129 // Only one instance of SOL is supported
130 if (request->payloadInstance != 1)
131 {
132 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
133 return outPayload;
134 }
135
Vernon Mauery9e801a22018-10-12 13:20:49 -0700136 auto status = std::get<sol::Manager&>(singletonPool)
137 .isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530138 if (!status)
139 {
140 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
141 return outPayload;
142 }
143
144 try
145 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700146 auto& context = std::get<sol::Manager&>(singletonPool)
147 .getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530148 auto sessionID = context.sessionID;
149
Vernon Mauery9e801a22018-10-12 13:20:49 -0700150 std::get<sol::Manager&>(singletonPool)
151 .stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530152
Tom Joseph6516cef2017-07-31 18:48:34 +0530153 try
154 {
155 activating(request->payloadInstance, sessionID);
156 }
157 catch (std::exception& e)
158 {
159 log<level::INFO>(e.what());
160 /*
161 * In case session has been closed (like in the case of inactivity
162 * timeout), then activating function would throw an exception,
163 * since sessionID is not found. IPMI success completion code is
164 * returned, since the session is closed.
165 */
166 return outPayload;
167 }
168
Vernon Mauery9e801a22018-10-12 13:20:49 -0700169 auto check =
170 std::get<session::Manager&>(singletonPool).stopSession(sessionID);
Tom Joseph6516cef2017-07-31 18:48:34 +0530171 if (!check)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530172 {
173 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
174 }
175 }
176 catch (std::exception& e)
177 {
178 log<level::ERR>(e.what());
179 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
180 return outPayload;
181 }
182
183 return outPayload;
184}
185
Tom Joseph18a45e92017-04-11 11:30:44 +0530186std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530187 const message::Handler& handler)
188{
189 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700190 auto request =
191 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
192 auto response =
193 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530194
195 // SOL is the payload currently supported for payload status
196 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
197 {
198 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
199 return outPayload;
200 }
201
202 response->completionCode = IPMI_CC_OK;
203 response->capacity = MAX_PAYLOAD_INSTANCES;
204
205 // Currently we support only one SOL session
206 response->instance1 =
Vernon Mauery9e801a22018-10-12 13:20:49 -0700207 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530208
209 return outPayload;
210}
211
Tom Joseph80938492018-03-22 10:05:20 +0530212std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
213 const message::Handler& handler)
214{
215 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700216 auto request =
217 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
218 auto response =
219 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530220
anil kumar appana35ca1502019-07-04 15:00:29 +0000221 if (inPayload.size() != sizeof(GetPayloadInfoRequest))
222 {
223 response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
224 return outPayload;
225 }
Tom Joseph80938492018-03-22 10:05:20 +0530226 // SOL is the payload currently supported for payload status & only one
227 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700228 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
229 request->payloadType ||
230 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530231 {
232 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
233 return outPayload;
234 }
Vernon Mauery9e801a22018-10-12 13:20:49 -0700235 auto status = std::get<sol::Manager&>(singletonPool)
236 .isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530237
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530238 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530239 {
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530240 auto& context = std::get<sol::Manager&>(singletonPool)
241 .getContext(request->payloadInstance);
242 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530243 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530244 else
245 {
246 // No active payload - return session id as 0
247 response->sessionID = 0;
248 }
249 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530250 return outPayload;
251}
252
Tom Joseph5c846a82017-04-03 01:59:39 +0530253} // namespace command
254
255} // namespace sol