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 .lock(); 62 63 message::Handler msgHandler(session->channelPtr, sessionID); 64 65 msgHandler.sendUnsolicitedIPMIPayload(netfnTransport, solActivatingCmd, 66 outPayload); 67 } 68 69 std::vector<uint8_t> setConfParams(const std::vector<uint8_t>& inPayload, 70 const message::Handler& handler) 71 { 72 std::vector<uint8_t> outPayload(sizeof(SetConfParamsResponse)); 73 auto request = 74 reinterpret_cast<const SetConfParamsRequest*>(inPayload.data()); 75 auto response = reinterpret_cast<SetConfParamsResponse*>(outPayload.data()); 76 response->completionCode = IPMI_CC_OK; 77 78 switch (static_cast<Parameter>(request->paramSelector)) 79 { 80 case Parameter::PROGRESS: 81 { 82 uint8_t progress = request->value & progressMask; 83 std::get<sol::Manager&>(singletonPool).progress = progress; 84 break; 85 } 86 case Parameter::ENABLE: 87 { 88 bool enable = request->value & enableMask; 89 std::get<sol::Manager&>(singletonPool).enable = enable; 90 break; 91 } 92 case Parameter::AUTHENTICATION: 93 { 94 if (!request->auth.auth || !request->auth.encrypt) 95 { 96 response->completionCode = ipmiCCWriteReadParameter; 97 } 98 else if (request->auth.privilege < 99 static_cast<uint8_t>(session::Privilege::USER) || 100 request->auth.privilege > 101 static_cast<uint8_t>(session::Privilege::OEM)) 102 { 103 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST; 104 } 105 else 106 { 107 std::get<sol::Manager&>(singletonPool).solMinPrivilege = 108 static_cast<session::Privilege>(request->auth.privilege); 109 } 110 break; 111 } 112 case Parameter::ACCUMULATE: 113 { 114 using namespace std::chrono_literals; 115 116 if (request->acc.threshold == 0) 117 { 118 response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST; 119 break; 120 } 121 122 std::get<sol::Manager&>(singletonPool).accumulateInterval = 123 request->acc.interval * sol::accIntervalFactor * 1ms; 124 std::get<sol::Manager&>(singletonPool).sendThreshold = 125 request->acc.threshold; 126 break; 127 } 128 case Parameter::RETRY: 129 { 130 using namespace std::chrono_literals; 131 132 std::get<sol::Manager&>(singletonPool).retryCount = 133 request->retry.count; 134 std::get<sol::Manager&>(singletonPool).retryInterval = 135 request->retry.interval * sol::retryIntervalFactor * 1ms; 136 break; 137 } 138 case Parameter::PORT: 139 { 140 response->completionCode = ipmiCCWriteReadParameter; 141 break; 142 } 143 case Parameter::NVBITRATE: 144 case Parameter::VBITRATE: 145 case Parameter::CHANNEL: 146 default: 147 response->completionCode = ipmiCCParamNotSupported; 148 } 149 150 return outPayload; 151 } 152 153 std::vector<uint8_t> getConfParams(const std::vector<uint8_t>& inPayload, 154 const message::Handler& handler) 155 { 156 std::vector<uint8_t> outPayload(sizeof(GetConfParamsResponse)); 157 auto request = 158 reinterpret_cast<const GetConfParamsRequest*>(inPayload.data()); 159 auto response = reinterpret_cast<GetConfParamsResponse*>(outPayload.data()); 160 response->completionCode = IPMI_CC_OK; 161 response->paramRev = parameterRevision; 162 163 if (request->getParamRev) 164 { 165 return outPayload; 166 } 167 168 switch (static_cast<Parameter>(request->paramSelector)) 169 { 170 case Parameter::PROGRESS: 171 { 172 outPayload.push_back( 173 std::get<sol::Manager&>(singletonPool).progress); 174 break; 175 } 176 case Parameter::ENABLE: 177 { 178 outPayload.push_back(std::get<sol::Manager&>(singletonPool).enable); 179 break; 180 } 181 case Parameter::AUTHENTICATION: 182 { 183 Auth value{0}; 184 185 value.encrypt = std::get<sol::Manager&>(singletonPool).forceEncrypt; 186 value.auth = std::get<sol::Manager&>(singletonPool).forceAuth; 187 value.privilege = static_cast<uint8_t>( 188 std::get<sol::Manager&>(singletonPool).solMinPrivilege); 189 auto buffer = reinterpret_cast<const uint8_t*>(&value); 190 191 std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload)); 192 break; 193 } 194 case Parameter::ACCUMULATE: 195 { 196 Accumulate value{0}; 197 198 value.interval = std::get<sol::Manager&>(singletonPool) 199 .accumulateInterval.count() / 200 sol::accIntervalFactor; 201 value.threshold = 202 std::get<sol::Manager&>(singletonPool).sendThreshold; 203 auto buffer = reinterpret_cast<const uint8_t*>(&value); 204 205 std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload)); 206 break; 207 } 208 case Parameter::RETRY: 209 { 210 Retry value{0}; 211 212 value.count = std::get<sol::Manager&>(singletonPool).retryCount; 213 value.interval = 214 std::get<sol::Manager&>(singletonPool).retryInterval.count() / 215 sol::retryIntervalFactor; 216 auto buffer = reinterpret_cast<const uint8_t*>(&value); 217 218 std::copy_n(buffer, sizeof(value), std::back_inserter(outPayload)); 219 break; 220 } 221 case Parameter::PORT: 222 { 223 auto port = endian::to_ipmi<uint16_t>(IPMI_STD_PORT); 224 auto buffer = reinterpret_cast<const uint8_t*>(&port); 225 226 std::copy_n(buffer, sizeof(port), std::back_inserter(outPayload)); 227 break; 228 } 229 case Parameter::CHANNEL: 230 { 231 outPayload.push_back( 232 std::get<sol::Manager&>(singletonPool).channel); 233 break; 234 } 235 case Parameter::NVBITRATE: 236 case Parameter::VBITRATE: 237 default: 238 response->completionCode = ipmiCCParamNotSupported; 239 } 240 241 return outPayload; 242 } 243 244 } // namespace command 245 246 } // namespace sol 247