blob: 3b5b4f8abc7954b00b1372481118c4435425a7f5 [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
104 // SOL is the payload currently supported for deactivation
105 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
106 {
107 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
108 return outPayload;
109 }
110
111 // Only one instance of SOL is supported
112 if (request->payloadInstance != 1)
113 {
114 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
115 return outPayload;
116 }
117
Vernon Mauery9e801a22018-10-12 13:20:49 -0700118 auto status = std::get<sol::Manager&>(singletonPool)
119 .isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530120 if (!status)
121 {
122 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
123 return outPayload;
124 }
125
126 try
127 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700128 auto& context = std::get<sol::Manager&>(singletonPool)
129 .getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530130 auto sessionID = context.sessionID;
131
Vernon Mauery9e801a22018-10-12 13:20:49 -0700132 std::get<sol::Manager&>(singletonPool)
133 .stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530134
Tom Joseph6516cef2017-07-31 18:48:34 +0530135 try
136 {
137 activating(request->payloadInstance, sessionID);
138 }
139 catch (std::exception& e)
140 {
141 log<level::INFO>(e.what());
142 /*
143 * In case session has been closed (like in the case of inactivity
144 * timeout), then activating function would throw an exception,
145 * since sessionID is not found. IPMI success completion code is
146 * returned, since the session is closed.
147 */
148 return outPayload;
149 }
150
Vernon Mauery9e801a22018-10-12 13:20:49 -0700151 auto check =
152 std::get<session::Manager&>(singletonPool).stopSession(sessionID);
Tom Joseph6516cef2017-07-31 18:48:34 +0530153 if (!check)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530154 {
155 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
156 }
157 }
158 catch (std::exception& e)
159 {
160 log<level::ERR>(e.what());
161 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
162 return outPayload;
163 }
164
165 return outPayload;
166}
167
Tom Joseph18a45e92017-04-11 11:30:44 +0530168std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530169 const message::Handler& handler)
170{
171 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700172 auto request =
173 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
174 auto response =
175 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530176
177 // SOL is the payload currently supported for payload status
178 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
179 {
180 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
181 return outPayload;
182 }
183
184 response->completionCode = IPMI_CC_OK;
185 response->capacity = MAX_PAYLOAD_INSTANCES;
186
187 // Currently we support only one SOL session
188 response->instance1 =
Vernon Mauery9e801a22018-10-12 13:20:49 -0700189 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530190
191 return outPayload;
192}
193
Tom Joseph80938492018-03-22 10:05:20 +0530194std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
195 const message::Handler& handler)
196{
197 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700198 auto request =
199 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
200 auto response =
201 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530202
203 // SOL is the payload currently supported for payload status & only one
204 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700205 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
206 request->payloadType ||
207 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530208 {
209 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
210 return outPayload;
211 }
212
Vernon Mauery9e801a22018-10-12 13:20:49 -0700213 auto status = std::get<sol::Manager&>(singletonPool)
214 .isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530215
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530216 if (status)
Tom Joseph80938492018-03-22 10:05:20 +0530217 {
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530218 auto& context = std::get<sol::Manager&>(singletonPool)
219 .getContext(request->payloadInstance);
220 response->sessionID = context.sessionID;
Tom Joseph80938492018-03-22 10:05:20 +0530221 }
Richard Marian Thomaiyar5f1dd312019-01-22 15:55:41 +0530222 else
223 {
224 // No active payload - return session id as 0
225 response->sessionID = 0;
226 }
227 response->completionCode = IPMI_CC_OK;
Tom Joseph80938492018-03-22 10:05:20 +0530228 return outPayload;
229}
230
Tom Joseph5c846a82017-04-03 01:59:39 +0530231} // namespace command
232
233} // namespace sol