blob: 8030b92ac9d28c59c912a1c6281d984e545f2ce3 [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
Vernon Mauery9e801a22018-10-12 13:20:49 -07007#include <host-ipmid/ipmid-api.h>
8
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 Mauery9e801a22018-10-12 13:20:49 -070050 auto session = (std::get<session::Manager&>(singletonPool)
51 .getSession(handler.sessionID))
52 .lock();
Tom Joseph5c846a82017-04-03 01:59:39 +053053
54 if (!request->encryption && session->isCryptAlgoEnabled())
55 {
56 response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
57 return outPayload;
58 }
59
Vernon Mauery9e801a22018-10-12 13:20:49 -070060 auto status = std::get<sol::Manager&>(singletonPool)
61 .isPayloadActive(request->payloadInstance);
Tom Joseph5c846a82017-04-03 01:59:39 +053062 if (status)
63 {
64 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
65 return outPayload;
66 }
67
68 // Set the current command's socket channel to the session
69 handler.setChannelInSession();
70
71 // Start the SOL payload
72 try
73 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070074 std::get<sol::Manager&>(singletonPool)
75 .startPayloadInstance(request->payloadInstance, handler.sessionID);
Tom Joseph5c846a82017-04-03 01:59:39 +053076 }
77 catch (std::exception& e)
78 {
79 log<level::ERR>(e.what());
80 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
81 return outPayload;
82 }
83
84 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
85 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
86 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
87
88 // VLAN addressing is not used
89 response->vlanNum = 0xFFFF;
90
91 return outPayload;
92}
93
Tom Joseph18a45e92017-04-11 11:30:44 +053094std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
Tom Josephe2f0a8e2017-04-03 02:01:49 +053095 const message::Handler& handler)
96{
97 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -070098 auto request =
99 reinterpret_cast<const DeactivatePayloadRequest*>(inPayload.data());
100 auto response =
101 reinterpret_cast<DeactivatePayloadResponse*>(outPayload.data());
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530102
103 response->completionCode = IPMI_CC_OK;
104
105 // SOL is the payload currently supported for deactivation
106 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
107 {
108 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
109 return outPayload;
110 }
111
112 // Only one instance of SOL is supported
113 if (request->payloadInstance != 1)
114 {
115 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
116 return outPayload;
117 }
118
Vernon Mauery9e801a22018-10-12 13:20:49 -0700119 auto status = std::get<sol::Manager&>(singletonPool)
120 .isPayloadActive(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530121 if (!status)
122 {
123 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
124 return outPayload;
125 }
126
127 try
128 {
Vernon Mauery9e801a22018-10-12 13:20:49 -0700129 auto& context = std::get<sol::Manager&>(singletonPool)
130 .getContext(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530131 auto sessionID = context.sessionID;
132
Vernon Mauery9e801a22018-10-12 13:20:49 -0700133 std::get<sol::Manager&>(singletonPool)
134 .stopPayloadInstance(request->payloadInstance);
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530135
Tom Joseph6516cef2017-07-31 18:48:34 +0530136 try
137 {
138 activating(request->payloadInstance, sessionID);
139 }
140 catch (std::exception& e)
141 {
142 log<level::INFO>(e.what());
143 /*
144 * In case session has been closed (like in the case of inactivity
145 * timeout), then activating function would throw an exception,
146 * since sessionID is not found. IPMI success completion code is
147 * returned, since the session is closed.
148 */
149 return outPayload;
150 }
151
Vernon Mauery9e801a22018-10-12 13:20:49 -0700152 auto check =
153 std::get<session::Manager&>(singletonPool).stopSession(sessionID);
Tom Joseph6516cef2017-07-31 18:48:34 +0530154 if (!check)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530155 {
156 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
157 }
158 }
159 catch (std::exception& e)
160 {
161 log<level::ERR>(e.what());
162 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
163 return outPayload;
164 }
165
166 return outPayload;
167}
168
Tom Joseph18a45e92017-04-11 11:30:44 +0530169std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530170 const message::Handler& handler)
171{
172 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700173 auto request =
174 reinterpret_cast<const GetPayloadStatusRequest*>(inPayload.data());
175 auto response =
176 reinterpret_cast<GetPayloadStatusResponse*>(outPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530177
178 // SOL is the payload currently supported for payload status
179 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
180 {
181 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
182 return outPayload;
183 }
184
185 response->completionCode = IPMI_CC_OK;
186 response->capacity = MAX_PAYLOAD_INSTANCES;
187
188 // Currently we support only one SOL session
189 response->instance1 =
Vernon Mauery9e801a22018-10-12 13:20:49 -0700190 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
Tom Josephe1ae56c2017-04-03 02:03:41 +0530191
192 return outPayload;
193}
194
Tom Joseph80938492018-03-22 10:05:20 +0530195std::vector<uint8_t> getPayloadInfo(const std::vector<uint8_t>& inPayload,
196 const message::Handler& handler)
197{
198 std::vector<uint8_t> outPayload(sizeof(GetPayloadInfoResponse));
Vernon Mauery9e801a22018-10-12 13:20:49 -0700199 auto request =
200 reinterpret_cast<const GetPayloadInfoRequest*>(inPayload.data());
201 auto response =
202 reinterpret_cast<GetPayloadInfoResponse*>(outPayload.data());
Tom Joseph80938492018-03-22 10:05:20 +0530203
204 // SOL is the payload currently supported for payload status & only one
205 // instance of SOL is supported.
Vernon Mauery9e801a22018-10-12 13:20:49 -0700206 if (static_cast<uint8_t>(message::PayloadType::SOL) !=
207 request->payloadType ||
208 request->payloadInstance != 1)
Tom Joseph80938492018-03-22 10:05:20 +0530209 {
210 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
211 return outPayload;
212 }
213
Vernon Mauery9e801a22018-10-12 13:20:49 -0700214 auto status = std::get<sol::Manager&>(singletonPool)
215 .isPayloadActive(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530216
217 if (!status)
218 {
219 response->completionCode = IPMI_CC_RESPONSE_ERROR;
220 return outPayload;
221 }
222
Vernon Mauery9e801a22018-10-12 13:20:49 -0700223 auto& context = std::get<sol::Manager&>(singletonPool)
224 .getContext(request->payloadInstance);
Tom Joseph80938492018-03-22 10:05:20 +0530225 response->sessionID = context.sessionID;
226
227 return outPayload;
228}
229
Tom Joseph5c846a82017-04-03 01:59:39 +0530230} // namespace command
231
232} // namespace sol