From 973865687325c6563fd6b729a3a220661066f635 Mon Sep 17 00:00:00 2001 From: Cheng C Yang Date: Wed, 3 Apr 2019 15:55:04 +0800 Subject: [PATCH] Move Get SOL config parameter to host-ipmid Move Get SOL config parameter command from net-ipmid to host-ipmid. Tested By: Run command ipmitool sol info Set in progress : set-complete Enabled : true Force Encryption : false Force Authentication : false Privilege Level : USER Character Accumulate Level (ms) : 100 Character Send Threshold : 1 Retry Count : 3 Retry Interval (ms) : 100 Volatile Bit Rate (kbps) : IPMI-Over-Serial-Setting Non-Volatile Bit Rate (kbps) : IPMI-Over-Serial-Setting Payload Channel : 14 (0x0e) Payload Port : 623 Signed-off-by: Cheng C Yang --- transporthandler.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++++++--- transporthandler.hpp | 26 +++++++++- 2 files changed, 156 insertions(+), 9 deletions(-) diff --git a/transporthandler.cpp b/transporthandler.cpp index 2111acf..b18f522 100644 --- a/transporthandler.cpp +++ b/transporthandler.cpp @@ -1715,11 +1715,133 @@ void initializeSOLInProgress() } } -ipmi_ret_t setConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_request_t request, ipmi_response_t response, - ipmi_data_len_t dataLen, ipmi_context_t context) +// For getsetSOLConfParams, there are still three tings TODO: +// 1. session less channel number request has to return error. +// 2. convert 0xE channel number. +// 3. have unique object for every session based channel. +ipmi_ret_t getSOLConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + ipmi_request_t request, ipmi_response_t response, + ipmi_data_len_t dataLen, ipmi_context_t context) { - auto reqData = reinterpret_cast(request); + auto reqData = reinterpret_cast(request); + std::vector outPayload; + + if (*dataLen < sizeof(GetSOLConfParamsRequest) - 2) + { + *dataLen = 0; + return IPMI_CC_REQ_DATA_LEN_INVALID; + } + + *dataLen = 0; + + outPayload.push_back(solParameterRevision); + if (reqData->getParamRev) + { + std::copy(outPayload.begin(), outPayload.end(), + static_cast(response)); + *dataLen = outPayload.size(); + return IPMI_CC_OK; + } + + ipmi::Value value; + switch (static_cast(reqData->paramSelector)) + { + case sol::Parameter::progress: + { + if (getSOLParameter("Progress", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + outPayload.push_back(std::get(value)); + break; + } + case sol::Parameter::enable: + { + if (getSOLParameter("Enable", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + outPayload.push_back(static_cast(std::get(value))); + break; + } + case sol::Parameter::authentication: + { + uint8_t authentication = 0; + if (getSOLParameter("Privilege", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + authentication = (std::get(value) & 0x0f); + + if (getSOLParameter("ForceAuthentication", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + authentication |= + (static_cast(std::get(value)) << 6); + + if (getSOLParameter("ForceEncryption", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + authentication |= + (static_cast(std::get(value)) << 7); + outPayload.push_back(authentication); + break; + } + case sol::Parameter::accumulate: + { + if (getSOLParameter("AccumulateIntervalMS", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + outPayload.push_back(std::get(value)); + + if (getSOLParameter("Threshold", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + outPayload.push_back(std::get(value)); + break; + } + case sol::Parameter::retry: + { + if (getSOLParameter("RetryCount", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + outPayload.push_back(std::get(value) & 0x03); + + if (getSOLParameter("RetryIntervalMS", value) < 0) + { + return IPMI_CC_UNSPECIFIED_ERROR; + } + outPayload.push_back(std::get(value)); + break; + } + case sol::Parameter::port: + { + uint16_t port = htole16(ipmiStdPort); + auto buffer = reinterpret_cast(&port); + std::copy(buffer, buffer + sizeof(port), + std::back_inserter(outPayload)); + break; + } + default: + return IPMI_CC_PARM_NOT_SUPPORTED; + } + std::copy(outPayload.begin(), outPayload.end(), + static_cast(response)); + *dataLen = outPayload.size(); + + return IPMI_CC_OK; +} + +ipmi_ret_t setSOLConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + ipmi_request_t request, ipmi_response_t response, + ipmi_data_len_t dataLen, ipmi_context_t context) +{ + auto reqData = reinterpret_cast(request); // Check request length first switch (static_cast(reqData->paramSelector)) @@ -1728,7 +1850,7 @@ ipmi_ret_t setConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd, case sol::Parameter::enable: case sol::Parameter::authentication: { - if (*dataLen != sizeof(SetConfParamsRequest) - 1) + if (*dataLen != sizeof(SetSOLConfParamsRequest) - 1) { *dataLen = 0; return IPMI_CC_REQ_DATA_LEN_INVALID; @@ -1738,7 +1860,7 @@ ipmi_ret_t setConfParams(ipmi_netfn_t netfn, ipmi_cmd_t cmd, case sol::Parameter::accumulate: case sol::Parameter::retry: { - if (*dataLen != sizeof(SetConfParamsRequest)) + if (*dataLen != sizeof(SetSOLConfParamsRequest)) { *dataLen = 0; return IPMI_CC_REQ_DATA_LEN_INVALID; @@ -1869,7 +1991,10 @@ void register_netfn_transport_functions() ipmi_transport_get_lan, PRIVILEGE_OPERATOR); ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_SET_SOL_CONF_PARAMS, NULL, - setConfParams, PRIVILEGE_ADMIN); + setSOLConfParams, PRIVILEGE_ADMIN); + + ipmi_register_callback(NETFUN_TRANSPORT, IPMI_CMD_GET_SOL_CONF_PARAMS, NULL, + getSOLConfParams, PRIVILEGE_ADMIN); // Initialize dbus property progress to 0 every time sol manager restart. initializeSOLInProgress(); diff --git a/transporthandler.hpp b/transporthandler.hpp index 3b5e9e1..7132cff 100644 --- a/transporthandler.hpp +++ b/transporthandler.hpp @@ -257,7 +257,7 @@ struct Retry uint8_t interval; //!< SOL retry interval. } __attribute__((packed)); -struct SetConfParamsRequest +struct SetSOLConfParamsRequest { #if BYTE_ORDER == LITTLE_ENDIAN uint8_t channelNumber : 4; //!< Channel number. @@ -279,7 +279,29 @@ struct SetConfParamsRequest }; } __attribute__((packed)); -struct SetConfParamsResponse +struct SetSOLConfParamsResponse { uint8_t completionCode; //!< Completion code. } __attribute__((packed)); + +struct GetSOLConfParamsRequest +{ +#if BYTE_ORDER == LITTLE_ENDIAN + uint8_t channelNum : 4; //!< Channel number. + uint8_t reserved : 3; //!< Reserved. + uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision +#endif + +#if BYTE_ORDER == BIG_ENDIAN + uint8_t getParamRev : 1; //!< Get parameter or Get parameter revision + uint8_t reserved : 3; //!< Reserved. + uint8_t channelNum : 4; //!< Channel number. +#endif + + uint8_t paramSelector; //!< Parameter selector. + uint8_t setSelector; //!< Set selector. + uint8_t blockSelector; //!< Block selector. +} __attribute__((packed)); + +static constexpr uint16_t ipmiStdPort = 623; +static constexpr uint8_t solParameterRevision = 0x11; -- 2.16.2