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 
2170fd29cfSVernon Mauery     std::vector<uint8_t> 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 
15620aef33bSTom Joseph std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload,
15720aef33bSTom Joseph                                    const message::Handler& handler)
15820aef33bSTom Joseph {
15920aef33bSTom Joseph     std::vector<uint8_t> outPayload(sizeof(GetConfParamsResponse));
16020aef33bSTom Joseph     auto request = reinterpret_cast<const GetConfParamsRequest*>
16120aef33bSTom Joseph                    (inPayload.data());
16220aef33bSTom Joseph     auto response = reinterpret_cast<GetConfParamsResponse*>
16320aef33bSTom Joseph                     (outPayload.data());
16420aef33bSTom Joseph     response->completionCode = IPMI_CC_OK;
16520aef33bSTom Joseph     response->paramRev = parameterRevision;
16620aef33bSTom Joseph 
16720aef33bSTom Joseph     if (request->getParamRev)
16820aef33bSTom Joseph     {
16920aef33bSTom Joseph         return outPayload;
17020aef33bSTom Joseph     }
17120aef33bSTom Joseph 
17220aef33bSTom Joseph     switch (static_cast<Parameter>(request->paramSelector))
17320aef33bSTom Joseph     {
17420aef33bSTom Joseph         case Parameter::PROGRESS:
17520aef33bSTom Joseph         {
17620aef33bSTom Joseph             outPayload.push_back(std::get<sol::Manager&>
17720aef33bSTom Joseph                     (singletonPool).progress);
17820aef33bSTom Joseph             break;
17920aef33bSTom Joseph         }
18020aef33bSTom Joseph         case Parameter::ENABLE:
18120aef33bSTom Joseph         {
18220aef33bSTom Joseph             outPayload.push_back(std::get<sol::Manager&>
18320aef33bSTom Joseph                     (singletonPool).enable);
18420aef33bSTom Joseph             break;
18520aef33bSTom Joseph         }
18620aef33bSTom Joseph         case Parameter::AUTHENTICATION:
18720aef33bSTom Joseph         {
18820aef33bSTom Joseph             Auth value {0};
18920aef33bSTom Joseph 
19020aef33bSTom Joseph             value.encrypt = std::get<sol::Manager&>(singletonPool).forceEncrypt;
19120aef33bSTom Joseph             value.auth = std::get<sol::Manager&>(singletonPool).forceAuth;
19220aef33bSTom Joseph             value.privilege  = static_cast<uint8_t>(std::get<sol::Manager&>
19320aef33bSTom Joseph                     (singletonPool).solMinPrivilege);
19420aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t *>(&value);
19520aef33bSTom Joseph 
19620aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
19720aef33bSTom Joseph             break;
19820aef33bSTom Joseph         }
19920aef33bSTom Joseph         case Parameter::ACCUMULATE:
20020aef33bSTom Joseph         {
20120aef33bSTom Joseph             Accumulate value {0};
20220aef33bSTom Joseph 
20320aef33bSTom Joseph             value.interval = std::get<sol::Manager&>(singletonPool)
20420aef33bSTom Joseph                             .accumulateInterval.count()/sol::accIntervalFactor;
20520aef33bSTom Joseph             value.threshold = std::get<sol::Manager&>
20620aef33bSTom Joseph                             (singletonPool).sendThreshold;
20720aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t *>(&value);
20820aef33bSTom Joseph 
20920aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
21020aef33bSTom Joseph             break;
21120aef33bSTom Joseph         }
21220aef33bSTom Joseph         case Parameter::RETRY:
21320aef33bSTom Joseph         {
21420aef33bSTom Joseph             Retry value {0};
21520aef33bSTom Joseph 
21620aef33bSTom Joseph             value.count = std::get<sol::Manager&>(singletonPool).retryCount;
21720aef33bSTom Joseph             value.interval = std::get<sol::Manager&>(singletonPool)
21820aef33bSTom Joseph                     .retryInterval.count()/sol::retryIntervalFactor;
21920aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t *>(&value);
22020aef33bSTom Joseph 
22120aef33bSTom Joseph             std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload));
22220aef33bSTom Joseph             break;
22320aef33bSTom Joseph         }
22420aef33bSTom Joseph         case Parameter::PORT:
22520aef33bSTom Joseph         {
22620aef33bSTom Joseph             auto port = endian::to_ipmi<uint16_t>(IPMI_STD_PORT);
22720aef33bSTom Joseph             auto buffer = reinterpret_cast<const uint8_t *>(&port);
22820aef33bSTom Joseph 
22920aef33bSTom Joseph             std::copy_n(buffer, sizeof(port), std::back_inserter(outPayload));
23020aef33bSTom Joseph             break;
23120aef33bSTom Joseph         }
232*6f83cbc9STom Joseph         case Parameter::CHANNEL:
233*6f83cbc9STom Joseph         {
234*6f83cbc9STom Joseph             outPayload.push_back(std::get<sol::Manager&>
235*6f83cbc9STom Joseph                     (singletonPool).channel);
236*6f83cbc9STom Joseph             break;
237*6f83cbc9STom Joseph         }
23820aef33bSTom Joseph         case Parameter::NVBITRATE:
23920aef33bSTom Joseph         case Parameter::VBITRATE:
24020aef33bSTom Joseph         default:
24120aef33bSTom Joseph             response->completionCode = ipmiCCParamNotSupported;
24220aef33bSTom Joseph     }
24320aef33bSTom Joseph 
24420aef33bSTom Joseph     return outPayload;
24520aef33bSTom Joseph }
24620aef33bSTom Joseph 
24764b3dec8STom Joseph } // namespace command
24864b3dec8STom Joseph 
24964b3dec8STom Joseph } // namespace sol
250