164b3dec8STom Joseph #include <phosphor-logging/log.hpp>
264b3dec8STom Joseph #include "main.hpp"
364b3dec8STom Joseph #include "sol/sol_context.hpp"
464b3dec8STom Joseph #include "sol/sol_manager.hpp"
564b3dec8STom Joseph #include "sol_cmds.hpp"
664b3dec8STom Joseph 
764b3dec8STom Joseph namespace sol
864b3dec8STom Joseph {
964b3dec8STom Joseph 
1064b3dec8STom Joseph namespace command
1164b3dec8STom Joseph {
1264b3dec8STom Joseph 
1364b3dec8STom Joseph using namespace phosphor::logging;
1464b3dec8STom Joseph 
1518a45e9dSTom Joseph std::vector<uint8_t> payloadHandler(const std::vector<uint8_t>& inPayload,
1664b3dec8STom Joseph                                     const message::Handler& handler)
1764b3dec8STom Joseph {
1818a45e9dSTom Joseph     auto request = reinterpret_cast<const Payload*>(inPayload.data());
1964b3dec8STom Joseph     auto solDataSize = inPayload.size() - sizeof(Payload);
2064b3dec8STom Joseph 
2164b3dec8STom Joseph     Buffer charData(solDataSize);
2264b3dec8STom Joseph     if( solDataSize > 0)
2364b3dec8STom Joseph     {
2464b3dec8STom Joseph         std::copy_n(inPayload.data() + sizeof(Payload),
2564b3dec8STom Joseph                     solDataSize,
2664b3dec8STom Joseph                     charData.begin());
2764b3dec8STom Joseph     }
2864b3dec8STom Joseph 
2964b3dec8STom Joseph     try
3064b3dec8STom Joseph     {
3164b3dec8STom Joseph         auto& context = std::get<sol::Manager&>(singletonPool).
3264b3dec8STom Joseph                 getContext(handler.sessionID);
3364b3dec8STom Joseph 
3464b3dec8STom Joseph         context.processInboundPayload(request->packetSeqNum,
3564b3dec8STom Joseph                                       request->packetAckSeqNum,
3664b3dec8STom Joseph                                       request->acceptedCharCount,
3764b3dec8STom Joseph                                       request->inOperation.ack,
3864b3dec8STom Joseph                                       charData);
3964b3dec8STom Joseph     }
4064b3dec8STom Joseph     catch (std::exception& e)
4164b3dec8STom Joseph     {
4264b3dec8STom Joseph         log<level::ERR>(e.what());
4364b3dec8STom Joseph         return std::vector<uint8_t>();
4464b3dec8STom Joseph     }
4564b3dec8STom Joseph 
4664b3dec8STom Joseph     return std::vector<uint8_t>();
4764b3dec8STom Joseph }
4864b3dec8STom Joseph 
49e14ac96fSTom Joseph void activating(uint8_t payloadInstance, uint32_t sessionID)
50e14ac96fSTom Joseph {
51e14ac96fSTom Joseph     std::vector<uint8_t> outPayload(sizeof(ActivatingRequest));
52e14ac96fSTom Joseph 
53e14ac96fSTom Joseph     auto request = reinterpret_cast<ActivatingRequest*>
54e14ac96fSTom Joseph                     (outPayload.data());
55e14ac96fSTom Joseph 
56e14ac96fSTom Joseph     request->sessionState = 0;
57e14ac96fSTom Joseph     request->payloadInstance = payloadInstance;
58e14ac96fSTom Joseph     request->majorVersion = MAJOR_VERSION;
59e14ac96fSTom Joseph     request->minorVersion = MINOR_VERSION;
60e14ac96fSTom Joseph 
61e14ac96fSTom Joseph     auto session = (std::get<session::Manager&>(singletonPool).getSession(
62e14ac96fSTom Joseph             sessionID)).lock();
63e14ac96fSTom Joseph 
64e14ac96fSTom Joseph     message::Handler msgHandler(session->channelPtr, sessionID);
65e14ac96fSTom Joseph 
66e14ac96fSTom Joseph     msgHandler.sendUnsolicitedIPMIPayload(netfnTransport,
67e14ac96fSTom Joseph                                           solActivatingCmd,
68e14ac96fSTom Joseph                                           outPayload);
69e14ac96fSTom Joseph }
70e14ac96fSTom Joseph 
7148b9951eSTom Joseph std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload,
7248b9951eSTom Joseph                                    const message::Handler& handler)
7348b9951eSTom Joseph {
7448b9951eSTom Joseph     std::vector<uint8_t> outPayload(sizeof(SetConfParamsResponse));
7548b9951eSTom Joseph     auto request = reinterpret_cast<const SetConfParamsRequest*>
7648b9951eSTom Joseph                    (inPayload.data());
7748b9951eSTom Joseph     auto response = reinterpret_cast<SetConfParamsResponse*>
7848b9951eSTom Joseph                     (outPayload.data());
7948b9951eSTom Joseph     response->completionCode = IPMI_CC_OK;
8048b9951eSTom Joseph 
8148b9951eSTom Joseph     switch (static_cast<Parameter>(request->paramSelector))
8248b9951eSTom Joseph     {
8348b9951eSTom Joseph         case Parameter::PROGRESS:
8448b9951eSTom Joseph         {
8548b9951eSTom Joseph             uint8_t progress = request->value & progressMask;
8648b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).progress = progress;
8748b9951eSTom Joseph             break;
8848b9951eSTom Joseph         }
8948b9951eSTom Joseph         case Parameter::ENABLE:
9048b9951eSTom Joseph         {
9148b9951eSTom Joseph             bool enable = request->value & enableMask;
9248b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).enable = enable;
9348b9951eSTom Joseph             break;
9448b9951eSTom Joseph         }
9548b9951eSTom Joseph         case Parameter::AUTHENTICATION:
9648b9951eSTom Joseph         {
9748b9951eSTom Joseph             if (!request->auth.auth || !request->auth.encrypt)
9848b9951eSTom Joseph             {
9948b9951eSTom Joseph                 response->completionCode = ipmiCCWriteReadParameter;
10048b9951eSTom Joseph             }
10148b9951eSTom Joseph             else if (request->auth.privilege <
10248b9951eSTom Joseph                      static_cast<uint8_t>(session::Privilege::USER) ||
10348b9951eSTom Joseph                      request->auth.privilege >
10448b9951eSTom Joseph                      static_cast<uint8_t>(session::Privilege::OEM))
10548b9951eSTom Joseph             {
10648b9951eSTom Joseph                 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
10748b9951eSTom Joseph             }
10848b9951eSTom Joseph             else
10948b9951eSTom Joseph             {
11048b9951eSTom Joseph                 std::get<sol::Manager&>(singletonPool).solMinPrivilege =
11148b9951eSTom Joseph                        static_cast<session::Privilege>(request->auth.privilege);
11248b9951eSTom Joseph             }
11348b9951eSTom Joseph             break;
11448b9951eSTom Joseph         }
11548b9951eSTom Joseph         case Parameter::ACCUMULATE:
11648b9951eSTom Joseph         {
11748b9951eSTom Joseph             using namespace std::chrono_literals;
11848b9951eSTom Joseph 
11948b9951eSTom Joseph             if (request->acc.threshold == 0)
12048b9951eSTom Joseph             {
12148b9951eSTom Joseph                 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
12248b9951eSTom Joseph                 break;
12348b9951eSTom Joseph             }
12448b9951eSTom Joseph 
12548b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).accumulateInterval =
12648b9951eSTom Joseph                     request->acc.interval * sol::accIntervalFactor * 1ms;
12748b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).sendThreshold =
12848b9951eSTom Joseph                     request->acc.threshold;
12948b9951eSTom Joseph             break;
13048b9951eSTom Joseph         }
13148b9951eSTom Joseph         case Parameter::RETRY:
13248b9951eSTom Joseph         {
13348b9951eSTom Joseph             using namespace std::chrono_literals;
13448b9951eSTom Joseph 
13548b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).retryCount =
13648b9951eSTom Joseph                     request->retry.count;
13748b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).retryInterval =
13848b9951eSTom Joseph                     request->retry.interval * sol::retryIntervalFactor * 1ms;
13948b9951eSTom Joseph             break;
14048b9951eSTom Joseph         }
14148b9951eSTom Joseph         case Parameter::PORT:
14248b9951eSTom Joseph         {
14348b9951eSTom Joseph             response->completionCode = ipmiCCWriteReadParameter;
14448b9951eSTom Joseph             break;
14548b9951eSTom Joseph         }
14648b9951eSTom Joseph         case Parameter::NVBITRATE:
14748b9951eSTom Joseph         case Parameter::VBITRATE:
14848b9951eSTom Joseph         case Parameter::CHANNEL:
14948b9951eSTom Joseph         default:
15048b9951eSTom Joseph             response->completionCode = ipmiCCParamNotSupported;
15148b9951eSTom Joseph     }
15248b9951eSTom Joseph 
15348b9951eSTom Joseph     return outPayload;
15448b9951eSTom Joseph }
15548b9951eSTom Joseph 
156*20aef33bSTom Joseph std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload,
157*20aef33bSTom Joseph                                    const message::Handler& handler)
158*20aef33bSTom Joseph {
159*20aef33bSTom Joseph     std::vector<uint8_t> outPayload(sizeof(GetConfParamsResponse));
160*20aef33bSTom Joseph     auto request = reinterpret_cast<const GetConfParamsRequest*>
161*20aef33bSTom Joseph                    (inPayload.data());
162*20aef33bSTom Joseph     auto response = reinterpret_cast<GetConfParamsResponse*>
163*20aef33bSTom Joseph                     (outPayload.data());
164*20aef33bSTom Joseph     response->completionCode = IPMI_CC_OK;
165*20aef33bSTom Joseph     response->paramRev = parameterRevision;
166*20aef33bSTom Joseph 
167*20aef33bSTom Joseph     if (request->getParamRev)
168*20aef33bSTom Joseph     {
169*20aef33bSTom Joseph         return outPayload;
170*20aef33bSTom Joseph     }
171*20aef33bSTom Joseph 
172*20aef33bSTom Joseph     switch (static_cast<Parameter>(request->paramSelector))
173*20aef33bSTom Joseph     {
174*20aef33bSTom Joseph         case Parameter::PROGRESS:
175*20aef33bSTom Joseph         {
176*20aef33bSTom Joseph             outPayload.push_back(std::get<sol::Manager&>
177*20aef33bSTom Joseph                     (singletonPool).progress);
178*20aef33bSTom Joseph             break;
179*20aef33bSTom Joseph         }
180*20aef33bSTom Joseph         case Parameter::ENABLE:
181*20aef33bSTom Joseph         {
182*20aef33bSTom Joseph             outPayload.push_back(std::get<sol::Manager&>
183*20aef33bSTom Joseph                     (singletonPool).enable);
184*20aef33bSTom Joseph             break;
185*20aef33bSTom Joseph         }
186*20aef33bSTom Joseph         case Parameter::AUTHENTICATION:
187*20aef33bSTom Joseph         {
188*20aef33bSTom Joseph             Auth value {0};
189*20aef33bSTom Joseph 
190*20aef33bSTom Joseph             value.encrypt = std::get<sol::Manager&>(singletonPool).forceEncrypt;
191*20aef33bSTom Joseph             value.auth = std::get<sol::Manager&>(singletonPool).forceAuth;
192*20aef33bSTom Joseph             value.privilege  = static_cast<uint8_t>(std::get<sol::Manager&>
193*20aef33bSTom Joseph                     (singletonPool).solMinPrivilege);
194*20aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t *>(&value);
195*20aef33bSTom Joseph 
196*20aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
197*20aef33bSTom Joseph             break;
198*20aef33bSTom Joseph         }
199*20aef33bSTom Joseph         case Parameter::ACCUMULATE:
200*20aef33bSTom Joseph         {
201*20aef33bSTom Joseph             Accumulate value {0};
202*20aef33bSTom Joseph 
203*20aef33bSTom Joseph             value.interval = std::get<sol::Manager&>(singletonPool)
204*20aef33bSTom Joseph                             .accumulateInterval.count()/sol::accIntervalFactor;
205*20aef33bSTom Joseph             value.threshold = std::get<sol::Manager&>
206*20aef33bSTom Joseph                             (singletonPool).sendThreshold;
207*20aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t *>(&value);
208*20aef33bSTom Joseph 
209*20aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
210*20aef33bSTom Joseph             break;
211*20aef33bSTom Joseph         }
212*20aef33bSTom Joseph         case Parameter::RETRY:
213*20aef33bSTom Joseph         {
214*20aef33bSTom Joseph             Retry value {0};
215*20aef33bSTom Joseph 
216*20aef33bSTom Joseph             value.count = std::get<sol::Manager&>(singletonPool).retryCount;
217*20aef33bSTom Joseph             value.interval = std::get<sol::Manager&>(singletonPool)
218*20aef33bSTom Joseph                     .retryInterval.count()/sol::retryIntervalFactor;
219*20aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t *>(&value);
220*20aef33bSTom Joseph 
221*20aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
222*20aef33bSTom Joseph             break;
223*20aef33bSTom Joseph         }
224*20aef33bSTom Joseph         case Parameter::PORT:
225*20aef33bSTom Joseph         {
226*20aef33bSTom Joseph             auto port = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
227*20aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t *>(&port);
228*20aef33bSTom Joseph 
229*20aef33bSTom Joseph             std::copy_n(buffer, sizeof(port), std::back_inserter(outPayload));
230*20aef33bSTom Joseph             break;
231*20aef33bSTom Joseph         }
232*20aef33bSTom Joseph         case Parameter::NVBITRATE:
233*20aef33bSTom Joseph         case Parameter::VBITRATE:
234*20aef33bSTom Joseph         case Parameter::CHANNEL:
235*20aef33bSTom Joseph         default:
236*20aef33bSTom Joseph             response->completionCode = ipmiCCParamNotSupported;
237*20aef33bSTom Joseph     }
238*20aef33bSTom Joseph 
239*20aef33bSTom Joseph     return outPayload;
240*20aef33bSTom Joseph }
241*20aef33bSTom Joseph 
24264b3dec8STom Joseph } // namespace command
24364b3dec8STom Joseph 
24464b3dec8STom Joseph } // namespace sol
245