blob: 2020722ffa0a04d350e707ff75d2b65a31a0cac4 [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
130 activating(request->payloadInstance, sessionID);
131 std::get<sol::Manager&>(singletonPool).stopPayloadInstance(
132 request->payloadInstance);
133
134 auto check = std::get<session::Manager&>(singletonPool).stopSession
135 (sessionID);
136 if(!check)
137 {
138 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
139 }
140 }
141 catch (std::exception& e)
142 {
143 log<level::ERR>(e.what());
144 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
145 return outPayload;
146 }
147
148 return outPayload;
149}
150
Tom Joseph18a45e92017-04-11 11:30:44 +0530151std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530152 const message::Handler& handler)
153{
154 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Tom Joseph18a45e92017-04-11 11:30:44 +0530155 auto request = reinterpret_cast<const GetPayloadStatusRequest*>
156 (inPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530157 auto response = reinterpret_cast<GetPayloadStatusResponse*>
158 (outPayload.data());
159
160 // SOL is the payload currently supported for payload status
161 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
162 {
163 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
164 return outPayload;
165 }
166
167 response->completionCode = IPMI_CC_OK;
168 response->capacity = MAX_PAYLOAD_INSTANCES;
169
170 // Currently we support only one SOL session
171 response->instance1 =
172 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
173
174 return outPayload;
175}
176
Tom Joseph5c846a82017-04-03 01:59:39 +0530177} // namespace command
178
179} // namespace sol