blob: 01e1117c8728d0b42383958449ea5bb6e8aa2c05 [file] [log] [blame]
Tom Joseph5c846a82017-04-03 01:59:39 +05301#include "payload_cmds.hpp"
Vernon Mauery9e801a22018-10-12 13:20:49 -07002
Vernon Mauery2085ae02021-06-10 11:51:00 -07003#include "sessions_manager.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,
Vernon Mauery41ff9b52021-06-11 11:37:40 -070021 std::shared_ptr<message::Handler>& handler)
Tom Joseph5c846a82017-04-03 01:59:39 +053022{
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
Vernon Mauery2085ae02021-06-10 11:51:00 -070044 sol::Manager::get().updateSOLParameter(ipmi::convertCurrentChannelNum(
45 ipmi::currentChNum, getInterfaceIndex()));
46 if (!sol::Manager::get().enable)
Tom Joseph96b6d812017-04-28 01:27:17 +053047 {
48 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
49 return outPayload;
50 }
51
Tom Joseph5c846a82017-04-03 01:59:39 +053052 // Only one instance of SOL is currently supported.
53 if (request->payloadInstance != 1)
54 {
55 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
56 return outPayload;
57 }
58
Vernon Mauery41ff9b52021-06-11 11:37:40 -070059 auto session = session::Manager::get().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 Mauery2085ae02021-06-10 11:51:00 -070079 auto status = sol::Manager::get().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
Vernon Mauery41ff9b52021-06-11 11:37:40 -070087 handler->setChannelInSession();
Tom Joseph5c846a82017-04-03 01:59:39 +053088
89 // Start the SOL payload
90 try
91 {
Vernon Mauery2085ae02021-06-10 11:51:00 -070092 sol::Manager::get().startPayloadInstance(request->payloadInstance,
Vernon Mauery41ff9b52021-06-11 11:37:40 -070093 handler->sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053094 }
Patrick Williams12d199b2021-10-06 12:36:48 -050095 catch (const std::exception& e)
Tom Joseph5c846a82017-04-03 01:59:39 +053096 {
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
Vernon Mauery41ff9b52021-06-11 11:37:40 -0700112std::vector<uint8_t>
113 deactivatePayload(const std::vector<uint8_t>& inPayload,
114 std::shared_ptr<message::Handler>& handler)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530115{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700116 auto request =
117 reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700118 if (inPayload.size() != sizeof(*request))
119 {
120 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
121 return errorPayload;
122 }
123
124 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700125 auto response =
126 reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530127 response->completionCode = IPMI_CC_OK;
128
129 // SOL is the payload currently supported for deactivation
130 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
131 {
132 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
133 return outPayload;
134 }
135
136 // Only one instance of SOL is supported
137 if (request->payloadInstance != 1)
138 {
139 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
140 return outPayload;
141 }
142
Vernon Mauery2085ae02021-06-10 11:51:00 -0700143 auto status = sol::Manager::get().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 Mauery2085ae02021-06-10 11:51:00 -0700152 auto& context =
153 sol::Manager::get().getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530154 auto sessionID = context.sessionID;
155
Vernon Mauery2085ae02021-06-10 11:51:00 -0700156 sol::Manager::get().stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530157
Tom Joseph6516cef2017-07-31 18:48:34 +0530158 try
159 {
160 activating(request->payloadInstance, sessionID);
161 }
Patrick Williams12d199b2021-10-06 12:36:48 -0500162 catch (const std::exception& e)
Tom Joseph6516cef2017-07-31 18:48:34 +0530163 {
164 log<level::INFO>(e.what());
165 /*
166 * In case session has been closed (like in the case of inactivity
167 * timeout), then activating function would throw an exception,
168 * since sessionID is not found. IPMI success completion code is
169 * returned, since the session is closed.
170 */
171 return outPayload;
172 }
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530173 }
Patrick Williams12d199b2021-10-06 12:36:48 -0500174 catch (const std::exception& e)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530175 {
176 log<level::ERR>(e.what());
177 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
178 return outPayload;
179 }
180
181 return outPayload;
182}
183
Vernon Mauery41ff9b52021-06-11 11:37:40 -0700184std::vector<uint8_t>
185 getPayloadStatus(const std::vector<uint8_t>& inPayload,
186 std::shared_ptr<message::Handler>& handler)
Tom Josephe1ae56c2017-04-03 02:03:41 +0530187{
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
Vernon Mauery2085ae02021-06-10 11:51:00 -0700213 response->instance1 = sol::Manager::get().isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530214
215 return outPayload;
216}
217
Tom Joseph80938492018-03-22 10:05:20 +0530218std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
Vernon Mauery41ff9b52021-06-11 11:37:40 -0700219 std::shared_ptr<message::Handler>& handler)
Tom Joseph80938492018-03-22 10:05:20 +0530220{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700221 auto request =
222 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
Zhikui Ren2b1edef2020-07-24 14:32:13 -0700223
224 if (inPayload.size() != sizeof(*request))
225 {
226 std::vector<uint8_t> errorPayload{IPMI_CC_REQ_DATA_LEN_INVALID};
227 return errorPayload;
228 }
229
230 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700231 auto response =
232 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530233
234 // 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 Mauery2085ae02021-06-10 11:51:00 -0700243 auto status = sol::Manager::get().isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530244
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530245 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530246 {
Vernon Mauery2085ae02021-06-10 11:51:00 -0700247 auto& context =
248 sol::Manager::get().getContext(request->payloadInstance);
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530249 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530250 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530251 else
252 {
253 // No active payload - return session id as 0
254 response->sessionID = 0;
255 }
256 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530257 return outPayload;
258}
259
Tom Joseph5c846a82017-04-03 01:59:39 +0530260} // namespace command
261
262} // namespace sol