blob: 1b69a33bdb34f683a6ba6a00d69c76a23a5449f5 [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
34 // Only one instance of SOL is currently supported.
35 if (request->payloadInstance != 1)
36 {
37 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
38 return outPayload;
39 }
40
41 auto session = (std::get<session::Manager&>(singletonPool).getSession(
42 handler.sessionID)).lock();
43
44 if (!request->encryption && session->isCryptAlgoEnabled())
45 {
46 response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION;
47 return outPayload;
48 }
49
50 auto status = std::get<sol::Manager&>(singletonPool).isPayloadActive(
51 request->payloadInstance);
52 if (status)
53 {
54 response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE;
55 return outPayload;
56 }
57
58 // Set the current command's socket channel to the session
59 handler.setChannelInSession();
60
61 // Start the SOL payload
62 try
63 {
64 std::get<sol::Manager&>(singletonPool).startPayloadInstance(
65 request->payloadInstance,
66 handler.sessionID);
67 }
68 catch (std::exception& e)
69 {
70 log<level::ERR>(e.what());
71 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
72 return outPayload;
73 }
74
75 response->inPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
76 response->outPayloadSize = endian::to_ipmi<uint16_t>(MAX_PAYLOAD_SIZE);
77 response->portNum = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
78
79 // VLAN addressing is not used
80 response->vlanNum = 0xFFFF;
81
82 return outPayload;
83}
84
Tom Joseph18a45e92017-04-11 11:30:44 +053085std::vector<uint8_t> deactivatePayload(const std::vector<uint8_t>& inPayload,
Tom Josephe2f0a8e2017-04-03 02:01:49 +053086 const message::Handler& handler)
87{
88 std::vector<uint8_t> outPayload(sizeof(DeactivatePayloadResponse));
Tom Joseph18a45e92017-04-11 11:30:44 +053089 auto request = reinterpret_cast<const DeactivatePayloadRequest*>
Tom Josephe2f0a8e2017-04-03 02:01:49 +053090 (inPayload.data());
91 auto response = reinterpret_cast<DeactivatePayloadResponse*>
92 (outPayload.data());
93
94 response->completionCode = IPMI_CC_OK;
95
96 // SOL is the payload currently supported for deactivation
97 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
98 {
99 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
100 return outPayload;
101 }
102
103 // Only one instance of SOL is supported
104 if (request->payloadInstance != 1)
105 {
106 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
107 return outPayload;
108 }
109
110 auto status = std::get<sol::Manager&>(singletonPool).isPayloadActive(
111 request->payloadInstance);
112 if (!status)
113 {
114 response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED;
115 return outPayload;
116 }
117
118 try
119 {
120 auto& context = std::get<sol::Manager&>(singletonPool).getContext
121 (request->payloadInstance);
122 auto sessionID = context.sessionID;
123
124 activating(request->payloadInstance, sessionID);
125 std::get<sol::Manager&>(singletonPool).stopPayloadInstance(
126 request->payloadInstance);
127
128 auto check = std::get<session::Manager&>(singletonPool).stopSession
129 (sessionID);
130 if(!check)
131 {
132 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
133 }
134 }
135 catch (std::exception& e)
136 {
137 log<level::ERR>(e.what());
138 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
139 return outPayload;
140 }
141
142 return outPayload;
143}
144
Tom Joseph18a45e92017-04-11 11:30:44 +0530145std::vector<uint8_t> getPayloadStatus(const std::vector<uint8_t>& inPayload,
Tom Josephe1ae56c2017-04-03 02:03:41 +0530146 const message::Handler& handler)
147{
148 std::vector<uint8_t> outPayload(sizeof(GetPayloadStatusResponse));
Tom Joseph18a45e92017-04-11 11:30:44 +0530149 auto request = reinterpret_cast<const GetPayloadStatusRequest*>
150 (inPayload.data());
Tom Josephe1ae56c2017-04-03 02:03:41 +0530151 auto response = reinterpret_cast<GetPayloadStatusResponse*>
152 (outPayload.data());
153
154 // SOL is the payload currently supported for payload status
155 if (static_cast<uint8_t>(message::PayloadType::SOL) != request->payloadType)
156 {
157 response->completionCode = IPMI_CC_UNSPECIFIED_ERROR;
158 return outPayload;
159 }
160
161 response->completionCode = IPMI_CC_OK;
162 response->capacity = MAX_PAYLOAD_INSTANCES;
163
164 // Currently we support only one SOL session
165 response->instance1 =
166 std::get<sol::Manager&>(singletonPool).isPayloadActive(1);
167
168 return outPayload;
169}
170
Tom Joseph5c846a82017-04-03 01:59:39 +0530171} // namespace command
172
173} // namespace sol