1*9e801a2bSVernon Mauery #include "sol_cmds.hpp"
2*9e801a2bSVernon Mauery 
364b3dec8STom Joseph #include "main.hpp"
464b3dec8STom Joseph #include "sol/sol_context.hpp"
564b3dec8STom Joseph #include "sol/sol_manager.hpp"
6*9e801a2bSVernon Mauery 
7*9e801a2bSVernon Mauery #include <phosphor-logging/log.hpp>
864b3dec8STom Joseph 
964b3dec8STom Joseph namespace sol
1064b3dec8STom Joseph {
1164b3dec8STom Joseph 
1264b3dec8STom Joseph namespace command
1364b3dec8STom Joseph {
1464b3dec8STom Joseph 
1564b3dec8STom Joseph using namespace phosphor::logging;
1664b3dec8STom Joseph 
1718a45e9dSTom Joseph std::vector<uint8_t> payloadHandler(const std::vector<uint8_t>& inPayload,
1864b3dec8STom Joseph                                     const message::Handler& handler)
1964b3dec8STom Joseph {
2018a45e9dSTom Joseph     auto request = reinterpret_cast<const Payload*>(inPayload.data());
2164b3dec8STom Joseph     auto solDataSize = inPayload.size() - sizeof(Payload);
2264b3dec8STom Joseph 
2370fd29cfSVernon Mauery     std::vector<uint8_t> charData(solDataSize);
2464b3dec8STom Joseph     if (solDataSize > 0)
2564b3dec8STom Joseph     {
26*9e801a2bSVernon Mauery         std::copy_n(inPayload.data() + sizeof(Payload), solDataSize,
2764b3dec8STom Joseph                     charData.begin());
2864b3dec8STom Joseph     }
2964b3dec8STom Joseph 
3064b3dec8STom Joseph     try
3164b3dec8STom Joseph     {
32*9e801a2bSVernon Mauery         auto& context = std::get<sol::Manager&>(singletonPool)
33*9e801a2bSVernon Mauery                             .getContext(handler.sessionID);
3464b3dec8STom Joseph 
35*9e801a2bSVernon Mauery         context.processInboundPayload(
36*9e801a2bSVernon Mauery             request->packetSeqNum, request->packetAckSeqNum,
37*9e801a2bSVernon Mauery             request->acceptedCharCount, request->inOperation.ack, charData);
3864b3dec8STom Joseph     }
3964b3dec8STom Joseph     catch (std::exception& e)
4064b3dec8STom Joseph     {
4164b3dec8STom Joseph         log<level::ERR>(e.what());
4264b3dec8STom Joseph         return std::vector<uint8_t>();
4364b3dec8STom Joseph     }
4464b3dec8STom Joseph 
4564b3dec8STom Joseph     return std::vector<uint8_t>();
4664b3dec8STom Joseph }
4764b3dec8STom Joseph 
48e14ac96fSTom Joseph void activating(uint8_t payloadInstance, uint32_t sessionID)
49e14ac96fSTom Joseph {
50e14ac96fSTom Joseph     std::vector<uint8_t> outPayload(sizeof(ActivatingRequest));
51e14ac96fSTom Joseph 
52*9e801a2bSVernon Mauery     auto request = reinterpret_cast<ActivatingRequest*>(outPayload.data());
53e14ac96fSTom Joseph 
54e14ac96fSTom Joseph     request->sessionState = 0;
55e14ac96fSTom Joseph     request->payloadInstance = payloadInstance;
56e14ac96fSTom Joseph     request->majorVersion = MAJOR_VERSION;
57e14ac96fSTom Joseph     request->minorVersion = MINOR_VERSION;
58e14ac96fSTom Joseph 
59*9e801a2bSVernon Mauery     auto session =
60*9e801a2bSVernon Mauery         (std::get<session::Manager&>(singletonPool).getSession(sessionID))
61*9e801a2bSVernon Mauery             .lock();
62e14ac96fSTom Joseph 
63e14ac96fSTom Joseph     message::Handler msgHandler(session->channelPtr, sessionID);
64e14ac96fSTom Joseph 
65*9e801a2bSVernon Mauery     msgHandler.sendUnsolicitedIPMIPayload(netfnTransport, solActivatingCmd,
66e14ac96fSTom Joseph                                           outPayload);
67e14ac96fSTom Joseph }
68e14ac96fSTom Joseph 
6948b9951eSTom Joseph std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload,
7048b9951eSTom Joseph                                    const message::Handler& handler)
7148b9951eSTom Joseph {
7248b9951eSTom Joseph     std::vector<uint8_t> outPayload(sizeof(SetConfParamsResponse));
73*9e801a2bSVernon Mauery     auto request =
74*9e801a2bSVernon Mauery         reinterpret_cast<const SetConfParamsRequest*>(inPayload.data());
75*9e801a2bSVernon Mauery     auto response = reinterpret_cast<SetConfParamsResponse*>(outPayload.data());
7648b9951eSTom Joseph     response->completionCode = IPMI_CC_OK;
7748b9951eSTom Joseph 
7848b9951eSTom Joseph     switch (static_cast<Parameter>(request->paramSelector))
7948b9951eSTom Joseph     {
8048b9951eSTom Joseph         case Parameter::PROGRESS:
8148b9951eSTom Joseph         {
8248b9951eSTom Joseph             uint8_t progress = request->value & progressMask;
8348b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).progress = progress;
8448b9951eSTom Joseph             break;
8548b9951eSTom Joseph         }
8648b9951eSTom Joseph         case Parameter::ENABLE:
8748b9951eSTom Joseph         {
8848b9951eSTom Joseph             bool enable = request->value & enableMask;
8948b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).enable = enable;
9048b9951eSTom Joseph             break;
9148b9951eSTom Joseph         }
9248b9951eSTom Joseph         case Parameter::AUTHENTICATION:
9348b9951eSTom Joseph         {
9448b9951eSTom Joseph             if (!request->auth.auth || !request->auth.encrypt)
9548b9951eSTom Joseph             {
9648b9951eSTom Joseph                 response->completionCode = ipmiCCWriteReadParameter;
9748b9951eSTom Joseph             }
9848b9951eSTom Joseph             else if (request->auth.privilege <
9948b9951eSTom Joseph                          static_cast<uint8_t>(session::Privilege::USER) ||
10048b9951eSTom Joseph                      request->auth.privilege >
10148b9951eSTom Joseph                          static_cast<uint8_t>(session::Privilege::OEM))
10248b9951eSTom Joseph             {
10348b9951eSTom Joseph                 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
10448b9951eSTom Joseph             }
10548b9951eSTom Joseph             else
10648b9951eSTom Joseph             {
10748b9951eSTom Joseph                 std::get<sol::Manager&>(singletonPool).solMinPrivilege =
10848b9951eSTom Joseph                     static_cast<session::Privilege>(request->auth.privilege);
10948b9951eSTom Joseph             }
11048b9951eSTom Joseph             break;
11148b9951eSTom Joseph         }
11248b9951eSTom Joseph         case Parameter::ACCUMULATE:
11348b9951eSTom Joseph         {
11448b9951eSTom Joseph             using namespace std::chrono_literals;
11548b9951eSTom Joseph 
11648b9951eSTom Joseph             if (request->acc.threshold == 0)
11748b9951eSTom Joseph             {
11848b9951eSTom Joseph                 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST;
11948b9951eSTom Joseph                 break;
12048b9951eSTom Joseph             }
12148b9951eSTom Joseph 
12248b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).accumulateInterval =
12348b9951eSTom Joseph                 request->acc.interval * sol::accIntervalFactor * 1ms;
12448b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).sendThreshold =
12548b9951eSTom Joseph                 request->acc.threshold;
12648b9951eSTom Joseph             break;
12748b9951eSTom Joseph         }
12848b9951eSTom Joseph         case Parameter::RETRY:
12948b9951eSTom Joseph         {
13048b9951eSTom Joseph             using namespace std::chrono_literals;
13148b9951eSTom Joseph 
13248b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).retryCount =
13348b9951eSTom Joseph                 request->retry.count;
13448b9951eSTom Joseph             std::get<sol::Manager&>(singletonPool).retryInterval =
13548b9951eSTom Joseph                 request->retry.interval * sol::retryIntervalFactor * 1ms;
13648b9951eSTom Joseph             break;
13748b9951eSTom Joseph         }
13848b9951eSTom Joseph         case Parameter::PORT:
13948b9951eSTom Joseph         {
14048b9951eSTom Joseph             response->completionCode = ipmiCCWriteReadParameter;
14148b9951eSTom Joseph             break;
14248b9951eSTom Joseph         }
14348b9951eSTom Joseph         case Parameter::NVBITRATE:
14448b9951eSTom Joseph         case Parameter::VBITRATE:
14548b9951eSTom Joseph         case Parameter::CHANNEL:
14648b9951eSTom Joseph         default:
14748b9951eSTom Joseph             response->completionCode = ipmiCCParamNotSupported;
14848b9951eSTom Joseph     }
14948b9951eSTom Joseph 
15048b9951eSTom Joseph     return outPayload;
15148b9951eSTom Joseph }
15248b9951eSTom Joseph 
15320aef33bSTom Joseph std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload,
15420aef33bSTom Joseph                                    const message::Handler& handler)
15520aef33bSTom Joseph {
15620aef33bSTom Joseph     std::vector<uint8_t> outPayload(sizeof(GetConfParamsResponse));
157*9e801a2bSVernon Mauery     auto request =
158*9e801a2bSVernon Mauery         reinterpret_cast<const GetConfParamsRequest*>(inPayload.data());
159*9e801a2bSVernon Mauery     auto response = reinterpret_cast<GetConfParamsResponse*>(outPayload.data());
16020aef33bSTom Joseph     response->completionCode = IPMI_CC_OK;
16120aef33bSTom Joseph     response->paramRev = parameterRevision;
16220aef33bSTom Joseph 
16320aef33bSTom Joseph     if (request->getParamRev)
16420aef33bSTom Joseph     {
16520aef33bSTom Joseph         return outPayload;
16620aef33bSTom Joseph     }
16720aef33bSTom Joseph 
16820aef33bSTom Joseph     switch (static_cast<Parameter>(request->paramSelector))
16920aef33bSTom Joseph     {
17020aef33bSTom Joseph         case Parameter::PROGRESS:
17120aef33bSTom Joseph         {
172*9e801a2bSVernon Mauery             outPayload.push_back(
173*9e801a2bSVernon Mauery                 std::get<sol::Manager&>(singletonPool).progress);
17420aef33bSTom Joseph             break;
17520aef33bSTom Joseph         }
17620aef33bSTom Joseph         case Parameter::ENABLE:
17720aef33bSTom Joseph         {
178*9e801a2bSVernon Mauery             outPayload.push_back(std::get<sol::Manager&>(singletonPool).enable);
17920aef33bSTom Joseph             break;
18020aef33bSTom Joseph         }
18120aef33bSTom Joseph         case Parameter::AUTHENTICATION:
18220aef33bSTom Joseph         {
18320aef33bSTom Joseph             Auth value{0};
18420aef33bSTom Joseph 
18520aef33bSTom Joseph             value.encrypt = std::get<sol::Manager&>(singletonPool).forceEncrypt;
18620aef33bSTom Joseph             value.auth = std::get<sol::Manager&>(singletonPool).forceAuth;
187*9e801a2bSVernon Mauery             value.privilege = static_cast<uint8_t>(
188*9e801a2bSVernon Mauery                 std::get<sol::Manager&>(singletonPool).solMinPrivilege);
18920aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t*>(&value);
19020aef33bSTom Joseph 
19120aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
19220aef33bSTom Joseph             break;
19320aef33bSTom Joseph         }
19420aef33bSTom Joseph         case Parameter::ACCUMULATE:
19520aef33bSTom Joseph         {
19620aef33bSTom Joseph             Accumulate value{0};
19720aef33bSTom Joseph 
19820aef33bSTom Joseph             value.interval = std::get<sol::Manager&>(singletonPool)
199*9e801a2bSVernon Mauery                                  .accumulateInterval.count() /
200*9e801a2bSVernon Mauery                              sol::accIntervalFactor;
201*9e801a2bSVernon Mauery             value.threshold =
202*9e801a2bSVernon Mauery                 std::get<sol::Manager&>(singletonPool).sendThreshold;
20320aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t*>(&value);
20420aef33bSTom Joseph 
20520aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
20620aef33bSTom Joseph             break;
20720aef33bSTom Joseph         }
20820aef33bSTom Joseph         case Parameter::RETRY:
20920aef33bSTom Joseph         {
21020aef33bSTom Joseph             Retry value{0};
21120aef33bSTom Joseph 
21220aef33bSTom Joseph             value.count = std::get<sol::Manager&>(singletonPool).retryCount;
213*9e801a2bSVernon Mauery             value.interval =
214*9e801a2bSVernon Mauery                 std::get<sol::Manager&>(singletonPool).retryInterval.count() /
215*9e801a2bSVernon Mauery                 sol::retryIntervalFactor;
21620aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t*>(&value);
21720aef33bSTom Joseph 
21820aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
21920aef33bSTom Joseph             break;
22020aef33bSTom Joseph         }
22120aef33bSTom Joseph         case Parameter::PORT:
22220aef33bSTom Joseph         {
22320aef33bSTom Joseph             auto port = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
22420aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t*>(&port);
22520aef33bSTom Joseph 
22620aef33bSTom Joseph             std::copy_n(buffer, sizeof(port), std::back_inserter(outPayload));
22720aef33bSTom Joseph             break;
22820aef33bSTom Joseph         }
2296f83cbc9STom Joseph         case Parameter::CHANNEL:
2306f83cbc9STom Joseph         {
231*9e801a2bSVernon Mauery             outPayload.push_back(
232*9e801a2bSVernon Mauery                 std::get<sol::Manager&>(singletonPool).channel);
2336f83cbc9STom Joseph             break;
2346f83cbc9STom Joseph         }
23520aef33bSTom Joseph         case Parameter::NVBITRATE:
23620aef33bSTom Joseph         case Parameter::VBITRATE:
23720aef33bSTom Joseph         default:
23820aef33bSTom Joseph             response->completionCode = ipmiCCParamNotSupported;
23920aef33bSTom Joseph     }
24020aef33bSTom Joseph 
24120aef33bSTom Joseph     return outPayload;
24220aef33bSTom Joseph }
24320aef33bSTom Joseph 
24464b3dec8STom Joseph } // namespace command
24564b3dec8STom Joseph 
24664b3dec8STom Joseph } // namespace sol
247