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