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