blob: c32a510f50bad3c7f41991bc809ab094c334048a [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
Vernon Mauery9e801a22018-10-12 13:20:49 -070059 auto status = std::get<sol::Manager&>(singletonPool)
60 .isPayloadActive(request->payloadInstance);
Tom Joseph5c846a82017-04-03 01:59:39 +053061 if (status)
62 {
63 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
64 return outPayload;
65 }
66
67 // Set the current command's socket channel to the session
68 handler.setChannelInSession();
69
70 // Start the SOL payload
71 try
72 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070073 std::get<sol::Manager&>(singletonPool)
74 .startPayloadInstance(request->payloadInstance, handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053075 }
76 catch (std::exception& e)
77 {
78 log<level::ERR>(e.what());
79 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
80 return outPayload;
81 }
82
83 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
84 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
85 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
86
87 // VLAN addressing is not used
88 response->vlanNum = 0xFFFF;
89
90 return outPayload;
91}
92
Tom Joseph18a45e92017-04-11 11:30:44 +053093std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
Tom Josephe2f0a8e2017-04-03 02:01:49 +053094 const message::Handler& handler)
95{
96 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -070097 auto request =
98 reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
99 auto response =
100 reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530101
102 response->completionCode = IPMI_CC_OK;
103
Sumanth Bhatb9631f82019-03-07 11:51:53 +0530104 if (inPayload.size() != sizeof(DeactivatePayloadRequest))
105 {
106 response->completionCode = IPMI_CC_REQ_DATA_LEN_INVALID;
107 return outPayload;
108 }
109
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530110 // SOL is the payload currently supported for deactivation
111 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
112 {
113 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
114 return outPayload;
115 }
116
117 // Only one instance of SOL is supported
118 if (request->payloadInstance != 1)
119 {
120 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
121 return outPayload;
122 }
123
Vernon Mauery9e801a22018-10-12 13:20:49 -0700124 auto status = std::get<sol::Manager&>(singletonPool)
125 .isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530126 if (!status)
127 {
128 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
129 return outPayload;
130 }
131
132 try
133 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700134 auto& context = std::get<sol::Manager&>(singletonPool)
135 .getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530136 auto sessionID = context.sessionID;
137
Vernon Mauery9e801a22018-10-12 13:20:49 -0700138 std::get<sol::Manager&>(singletonPool)
139 .stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530140
Tom Joseph6516cef2017-07-31 18:48:34 +0530141 try
142 {
143 activating(request->payloadInstance, sessionID);
144 }
145 catch (std::exception& e)
146 {
147 log<level::INFO>(e.what());
148 /*
149 * In case session has been closed (like in the case of inactivity
150 * timeout), then activating function would throw an exception,
151 * since sessionID is not found. IPMI success completion code is
152 * returned, since the session is closed.
153 */
154 return outPayload;
155 }
156
Vernon Mauery9e801a22018-10-12 13:20:49 -0700157 auto check =
158 std::get<session::Manager&>(singletonPool).stopSession(sessionID);
Tom Joseph6516cef2017-07-31 18:48:34 +0530159 if (!check)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530160 {
161 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
162 }
163 }
164 catch (std::exception& e)
165 {
166 log<level::ERR>(e.what());
167 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
168 return outPayload;
169 }
170
171 return outPayload;
172}
173
Tom Joseph18a45e92017-04-11 11:30:44 +0530174std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530175 const message::Handler& handler)
176{
177 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700178 auto request =
179 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
180 auto response =
181 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530182
183 // SOL is the payload currently supported for payload status
184 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
185 {
186 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
187 return outPayload;
188 }
189
190 response->completionCode = IPMI_CC_OK;
191 response->capacity = MAX_PAYLOAD_INSTANCES;
192
193 // Currently we support only one SOL session
194 response->instance1 =
Vernon Mauery9e801a22018-10-12 13:20:49 -0700195 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530196
197 return outPayload;
198}
199
Tom Joseph80938492018-03-22 10:05:20 +0530200std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
201 const message::Handler& handler)
202{
203 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700204 auto request =
205 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
206 auto response =
207 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530208
209 // SOL is the payload currently supported for payload status & only one
210 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700211 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
212 request->payloadType ||
213 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530214 {
215 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
216 return outPayload;
217 }
218
Vernon Mauery9e801a22018-10-12 13:20:49 -0700219 auto status = std::get<sol::Manager&>(singletonPool)
220 .isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530221
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530222 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530223 {
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530224 auto& context = std::get<sol::Manager&>(singletonPool)
225 .getContext(request->payloadInstance);
226 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530227 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530228 else
229 {
230 // No active payload - return session id as 0
231 response->sessionID = 0;
232 }
233 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530234 return outPayload;
235}
236
Tom Joseph5c846a82017-04-03 01:59:39 +0530237} // namespace command
238
239} // namespace sol