1 #include <phosphor-logging/log.hpp>
2 #include "main.hpp"
3 #include "sol/sol_context.hpp"
4 #include "sol/sol_manager.hpp"
5 #include "sol_cmds.hpp"
6 
7 namespace sol
8 {
9 
10 namespace command
11 {
12 
13 using namespace phosphor::logging;
14 
15 std::vector<uint8_t> payloadHandler(const std::vector<uint8_t>& inPayload,
16                                     const message::Handler& handler)
17 {
18     auto request = reinterpret_cast<const Payload*>(inPayload.data());
19     auto solDataSize = inPayload.size() - sizeof(Payload);
20 
21     std::vector<uint8_t> charData(solDataSize);
22     if( solDataSize > 0)
23     {
24         std::copy_n(inPayload.data() + sizeof(Payload),
25                     solDataSize,
26                     charData.begin());
27     }
28 
29     try
30     {
31         auto& context = std::get<sol::Manager&>(singletonPool).
32                 getContext(handler.sessionID);
33 
34         context.processInboundPayload(request->packetSeqNum,
35                                       request->packetAckSeqNum,
36                                       request->acceptedCharCount,
37                                       request->inOperation.ack,
38                                       charData);
39     }
40     catch (std::exception& e)
41     {
42         log<level::ERR>(e.what());
43         return std::vector<uint8_t>();
44     }
45 
46     return std::vector<uint8_t>();
47 }
48 
49 void activating(uint8_t payloadInstance, uint32_t sessionID)
50 {
51     std::vector<uint8_t> outPayload(sizeof(ActivatingRequest));
52 
53     auto request = reinterpret_cast<ActivatingRequest*>
54                     (outPayload.data());
55 
56     request->sessionState = 0;
57     request->payloadInstance = payloadInstance;
58     request->majorVersion = MAJOR_VERSION;
59     request->minorVersion = MINOR_VERSION;
60 
61     auto session = (std::get<session::Manager&>(singletonPool).getSession(
62             sessionID)).lock();
63 
64     message::Handler msgHandler(session->channelPtr, sessionID);
65 
66     msgHandler.sendUnsolicitedIPMIPayload(netfnTransport,
67                                           solActivatingCmd,
68                                           outPayload);
69 }
70 
71 std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload,
72                                    const message::Handler& handler)
73 {
74     std::vector<uint8_t> outPayload(sizeof(SetConfParamsResponse));
75     auto request = reinterpret_cast<const SetConfParamsRequest*>
76                    (inPayload.data());
77     auto response = reinterpret_cast<SetConfParamsResponse*>
78                     (outPayload.data());
79     response->completionCode = IPMI_CC_OK;
80 
81     switch (static_cast<Parameter>(request->paramSelector))
82     {
83         case Parameter::PROGRESS:
84         {
85             uint8_t progress = request->value & progressMask;
86             std::get<sol::Manager&>(singletonPool).progress = progress;
87             break;
88         }
89         case Parameter::ENABLE:
90         {
91             bool enable = request->value & enableMask;
92             std::get<sol::Manager&>(singletonPool).enable = enable;
93             break;
94         }
95         case Parameter::AUTHENTICATION:
96         {
97             if (!request->auth.auth || !request->auth.encrypt)
98             {
99                 response->completionCode = ipmiCCWriteReadParameter;
100             }
101             else if (request->auth.privilege <
102                      static_cast<uint8_t>(session::Privilege::USER) ||
103                      request->auth.privilege >
104                      static_cast<uint8_t>(session::Privilege::OEM))
105             {
106                 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
107             }
108             else
109             {
110                 std::get<sol::Manager&>(singletonPool).solMinPrivilege =
111                        static_cast<session::Privilege>(request->auth.privilege);
112             }
113             break;
114         }
115         case Parameter::ACCUMULATE:
116         {
117             using namespace std::chrono_literals;
118 
119             if (request->acc.threshold == 0)
120             {
121                 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
122                 break;
123             }
124 
125             std::get<sol::Manager&>(singletonPool).accumulateInterval =
126                     request->acc.interval * sol::accIntervalFactor * 1ms;
127             std::get<sol::Manager&>(singletonPool).sendThreshold =
128                     request->acc.threshold;
129             break;
130         }
131         case Parameter::RETRY:
132         {
133             using namespace std::chrono_literals;
134 
135             std::get<sol::Manager&>(singletonPool).retryCount =
136                     request->retry.count;
137             std::get<sol::Manager&>(singletonPool).retryInterval =
138                     request->retry.interval * sol::retryIntervalFactor * 1ms;
139             break;
140         }
141         case Parameter::PORT:
142         {
143             response->completionCode = ipmiCCWriteReadParameter;
144             break;
145         }
146         case Parameter::NVBITRATE:
147         case Parameter::VBITRATE:
148         case Parameter::CHANNEL:
149         default:
150             response->completionCode = ipmiCCParamNotSupported;
151     }
152 
153     return outPayload;
154 }
155 
156 std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload,
157                                    const message::Handler& handler)
158 {
159     std::vector<uint8_t> outPayload(sizeof(GetConfParamsResponse));
160     auto request = reinterpret_cast<const GetConfParamsRequest*>
161                    (inPayload.data());
162     auto response = reinterpret_cast<GetConfParamsResponse*>
163                     (outPayload.data());
164     response->completionCode = IPMI_CC_OK;
165     response->paramRev = parameterRevision;
166 
167     if (request->getParamRev)
168     {
169         return outPayload;
170     }
171 
172     switch (static_cast<Parameter>(request->paramSelector))
173     {
174         case Parameter::PROGRESS:
175         {
176             outPayload.push_back(std::get<sol::Manager&>
177                     (singletonPool).progress);
178             break;
179         }
180         case Parameter::ENABLE:
181         {
182             outPayload.push_back(std::get<sol::Manager&>
183                     (singletonPool).enable);
184             break;
185         }
186         case Parameter::AUTHENTICATION:
187         {
188             Auth value {0};
189 
190             value.encrypt = std::get<sol::Manager&>(singletonPool).forceEncrypt;
191             value.auth = std::get<sol::Manager&>(singletonPool).forceAuth;
192             value.privilege  = static_cast<uint8_t>(std::get<sol::Manager&>
193                     (singletonPool).solMinPrivilege);
194             auto buffer = reinterpret_cast<const uint8_t *>(&value);
195 
196             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
197             break;
198         }
199         case Parameter::ACCUMULATE:
200         {
201             Accumulate value {0};
202 
203             value.interval = std::get<sol::Manager&>(singletonPool)
204                             .accumulateInterval.count()/sol::accIntervalFactor;
205             value.threshold = std::get<sol::Manager&>
206                             (singletonPool).sendThreshold;
207             auto buffer = reinterpret_cast<const uint8_t *>(&value);
208 
209             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
210             break;
211         }
212         case Parameter::RETRY:
213         {
214             Retry value {0};
215 
216             value.count = std::get<sol::Manager&>(singletonPool).retryCount;
217             value.interval = std::get<sol::Manager&>(singletonPool)
218                     .retryInterval.count()/sol::retryIntervalFactor;
219             auto buffer = reinterpret_cast<const uint8_t *>(&value);
220 
221             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
222             break;
223         }
224         case Parameter::PORT:
225         {
226             auto port = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
227             auto buffer = reinterpret_cast<const uint8_t *>(&port);
228 
229             std::copy_n(buffer, sizeof(port), std::back_inserter(outPayload));
230             break;
231         }
232         case Parameter::NVBITRATE:
233         case Parameter::VBITRATE:
234         case Parameter::CHANNEL:
235         default:
236             response->completionCode = ipmiCCParamNotSupported;
237     }
238 
239     return outPayload;
240 }
241 
242 } // namespace command
243 
244 } // namespace sol
245