blob: 0cc52cc1713ee5bcda1caefa05bce8c167166b04 [file] [log] [blame]
Tom Joseph5c846a82017-04-03 01:59:39 +05301#include <host-ipmid/ipmid-api.h>
2#include <phosphor-logging/log.hpp>
3#include "main.hpp"
4#include "payload_cmds.hpp"
5#include "sol/sol_manager.hpp"
6#include "sol_cmds.hpp"
7
8namespace sol
9{
10
11namespace command
12{
13
14using namespace phosphor::logging;
15
Tom Joseph18a45e92017-04-11 11:30:44 +053016std::vector<uint8_t> activatePayload(const std::vector<uint8_t>& inPayload,
Tom Joseph5c846a82017-04-03 01:59:39 +053017 const message::Handler& handler)
18{
19 std::vector<uint8_t> outPayload(sizeof(ActivatePayloadResponse));
Tom Joseph18a45e92017-04-11 11:30:44 +053020 auto request = reinterpret_cast<const ActivatePayloadRequest*>
21 (inPayload.data());
Tom Joseph5c846a82017-04-03 01:59:39 +053022 auto response = reinterpret_cast<ActivatePayloadResponse*>
23 (outPayload.data());
24
25 response->completionCode = IPMI_CC_OK;
26
27 // SOL is the payload currently supported for activation.
28 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
29 {
30 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
31 return outPayload;
32 }
33
Tom Joseph96b6d812017-04-28 01:27:17 +053034 if (!std::get<sol::Manager&>(singletonPool).enable)
35 {
36 response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED;
37 return outPayload;
38 }
39
Tom Joseph5c846a82017-04-03 01:59:39 +053040 // Only one instance of SOL is currently supported.
41 if (request->payloadInstance != 1)
42 {
43 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
44 return outPayload;
45 }
46
47 auto session = (std::get<session::Manager&>(singletonPool).getSession(
48 handler.sessionID)).lock();
49
50 if (!request->encryption && session->isCryptAlgoEnabled())
51 {
52 response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
53 return outPayload;
54 }
55
56 auto status = std::get<sol::Manager&>(singletonPool).isPayloadActive(
57 request->payloadInstance);
58 if (status)
59 {
60 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
61 return outPayload;
62 }
63
64 // Set the current command's socket channel to the session
65 handler.setChannelInSession();
66
67 // Start the SOL payload
68 try
69 {
70 std::get<sol::Manager&>(singletonPool).startPayloadInstance(
71 request->payloadInstance,
72 handler.sessionID);
73 }
74 catch (std::exception& e)
75 {
76 log<level::ERR>(e.what());
77 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
78 return outPayload;
79 }
80
81 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
82 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
83 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
84
85 // VLAN addressing is not used
86 response->vlanNum = 0xFFFF;
87
88 return outPayload;
89}
90
Tom Joseph18a45e92017-04-11 11:30:44 +053091std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
Tom Josephe2f0a8e2017-04-03 02:01:49 +053092 const message::Handler& handler)
93{
94 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Tom Joseph18a45e92017-04-11 11:30:44 +053095 auto request = reinterpret_cast<const DeactivatePayloadRequest*>
Tom Josephe2f0a8e2017-04-03 02:01:49 +053096 (inPayload.data());
97 auto response = reinterpret_cast<DeactivatePayloadResponse*>
98 (outPayload.data());
99
100 response->completionCode = IPMI_CC_OK;
101
102 // SOL is the payload currently supported for deactivation
103 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
104 {
105 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
106 return outPayload;
107 }
108
109 // Only one instance of SOL is supported
110 if (request->payloadInstance != 1)
111 {
112 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
113 return outPayload;
114 }
115
116 auto status = std::get<sol::Manager&>(singletonPool).isPayloadActive(
117 request->payloadInstance);
118 if (!status)
119 {
120 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
121 return outPayload;
122 }
123
124 try
125 {
126 auto& context = std::get<sol::Manager&>(singletonPool).getContext
127 (request->payloadInstance);
128 auto sessionID = context.sessionID;
129
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530130 std::get<sol::Manager&>(singletonPool).stopPayloadInstance(
131 request->payloadInstance);
132
Tom Joseph6516cef2017-07-31 18:48:34 +0530133 try
134 {
135 activating(request->payloadInstance, sessionID);
136 }
137 catch (std::exception& e)
138 {
139 log<level::INFO>(e.what());
140 /*
141 * In case session has been closed (like in the case of inactivity
142 * timeout), then activating function would throw an exception,
143 * since sessionID is not found. IPMI success completion code is
144 * returned, since the session is closed.
145 */
146 return outPayload;
147 }
148
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530149 auto check = std::get<session::Manager&>(singletonPool).stopSession
150 (sessionID);
Tom Joseph6516cef2017-07-31 18:48:34 +0530151 if (!check)
Tom Josephe2f0a8e2017-04-03 02:01:49 +0530152 {
153 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
154 }
155 }
156 catch (std::exception& e)
157 {
158 log<level::ERR>(e.what());
159 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
160 return outPayload;
161 }
162
163 return outPayload;
164}
165
Tom Joseph18a45e92017-04-11 11:30:44 +0530166std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530167 const message::Handler& handler)
168{
169 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Tom Joseph18a45e92017-04-11 11:30:44 +0530170 auto request = reinterpret_cast<const GetPayloadStatusRequest*>
171 (inPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530172 auto response = reinterpret_cast<GetPayloadStatusResponse*>
173 (outPayload.data());
174
175 // SOL is the payload currently supported for payload status
176 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
177 {
178 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
179 return outPayload;
180 }
181
182 response->completionCode = IPMI_CC_OK;
183 response->capacity = MAX_PAYLOAD_INSTANCES;
184
185 // Currently we support only one SOL session
186 response->instance1 =
187 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
188
189 return outPayload;
190}
191
Tom Joseph5c846a82017-04-03 01:59:39 +0530192} // namespace command
193
194} // namespace sol