#include #include #include "main.hpp" #include "payload_cmds.hpp" #include "sol/sol_manager.hpp" #include "sol_cmds.hpp" namespace sol { namespace command { using namespace phosphor::logging; std::vector activatePayload(const std::vector& inPayload, const message::Handler& handler) { std::vector outPayload(sizeof(ActivatePayloadResponse)); auto request = reinterpret_cast (inPayload.data()); auto response = reinterpret_cast (outPayload.data()); response->completionCode = IPMI_CC_OK; // SOL is the payload currently supported for activation. if (static_cast(message::PayloadType::SOL) != request->payloadType) { response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST; return outPayload; } if (!std::get(singletonPool).enable) { response->completionCode = IPMI_CC_PAYLOAD_TYPE_DISABLED; return outPayload; } // Only one instance of SOL is currently supported. if (request->payloadInstance != 1) { response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST; return outPayload; } auto session = (std::get(singletonPool).getSession( handler.sessionID)).lock(); if (!request->encryption && session->isCryptAlgoEnabled()) { response->completionCode = IPMI_CC_PAYLOAD_WITHOUT_ENCRYPTION; return outPayload; } auto status = std::get(singletonPool).isPayloadActive( request->payloadInstance); if (status) { response->completionCode = IPMI_CC_PAYLOAD_ALREADY_ACTIVE; return outPayload; } // Set the current command's socket channel to the session handler.setChannelInSession(); // Start the SOL payload try { std::get(singletonPool).startPayloadInstance( request->payloadInstance, handler.sessionID); } catch (std::exception& e) { log(e.what()); response->completionCode = IPMI_CC_UNSPECIFIED_ERROR; return outPayload; } response->inPayloadSize = endian::to_ipmi(MAX_PAYLOAD_SIZE); response->outPayloadSize = endian::to_ipmi(MAX_PAYLOAD_SIZE); response->portNum = endian::to_ipmi(IPMI_STD_PORT); // VLAN addressing is not used response->vlanNum = 0xFFFF; return outPayload; } std::vector deactivatePayload(const std::vector& inPayload, const message::Handler& handler) { std::vector outPayload(sizeof(DeactivatePayloadResponse)); auto request = reinterpret_cast (inPayload.data()); auto response = reinterpret_cast (outPayload.data()); response->completionCode = IPMI_CC_OK; // SOL is the payload currently supported for deactivation if (static_cast(message::PayloadType::SOL) != request->payloadType) { response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST; return outPayload; } // Only one instance of SOL is supported if (request->payloadInstance != 1) { response->completionCode = IPMI_CC_INVALID_FIELD_REQUEST; return outPayload; } auto status = std::get(singletonPool).isPayloadActive( request->payloadInstance); if (!status) { response->completionCode = IPMI_CC_PAYLOAD_DEACTIVATED; return outPayload; } try { auto& context = std::get(singletonPool).getContext (request->payloadInstance); auto sessionID = context.sessionID; std::get(singletonPool).stopPayloadInstance( request->payloadInstance); try { activating(request->payloadInstance, sessionID); } catch (std::exception& e) { log(e.what()); /* * In case session has been closed (like in the case of inactivity * timeout), then activating function would throw an exception, * since sessionID is not found. IPMI success completion code is * returned, since the session is closed. */ return outPayload; } auto check = std::get(singletonPool).stopSession (sessionID); if (!check) { response->completionCode = IPMI_CC_UNSPECIFIED_ERROR; } } catch (std::exception& e) { log(e.what()); response->completionCode = IPMI_CC_UNSPECIFIED_ERROR; return outPayload; } return outPayload; } std::vector getPayloadStatus(const std::vector& inPayload, const message::Handler& handler) { std::vector outPayload(sizeof(GetPayloadStatusResponse)); auto request = reinterpret_cast (inPayload.data()); auto response = reinterpret_cast (outPayload.data()); // SOL is the payload currently supported for payload status if (static_cast(message::PayloadType::SOL) != request->payloadType) { response->completionCode = IPMI_CC_UNSPECIFIED_ERROR; return outPayload; } response->completionCode = IPMI_CC_OK; response->capacity = MAX_PAYLOAD_INSTANCES; // Currently we support only one SOL session response->instance1 = std::get(singletonPool).isPayloadActive(1); return outPayload; } } // namespace command } // namespace sol