From e8ad148601fc3b45fac9092fdd45c537433e662f Mon Sep 17 00:00:00 2001 From: Cheng C Yang Date: Thu, 11 Jul 2019 00:32:58 +0800 Subject: [PATCH] Move Get SOL config parameter to host-ipmid Move Get SOL config parameter command from net-ipmid to host-ipmid. Tested: Run command ipmitool sol info 1 Set in progress : set-complete Enabled : true Force Encryption : false Force Authentication : false Privilege Level : ADMINISTRATOR Character Accumulate Level (ms) : 60 Character Send Threshold : 96 Retry Count : 6 Retry Interval (ms) : 200 Volatile Bit Rate (kbps) : IPMI-Over-Serial-Setting Non-Volatile Bit Rate (kbps) : 115.2 Payload Channel : 1 (0x01) Payload Port : 623 Signed-off-by: Cheng C Yang --- host-ipmid-whitelist.conf | 1 + transporthandler.cpp | 191 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+) diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf index 44c2181..0fcac4e 100644 --- a/host-ipmid-whitelist.conf +++ b/host-ipmid-whitelist.conf @@ -41,6 +41,7 @@ 0x0A:0x49 //: 0x0C:0x02 //: 0x0C:0x21 //: +0x0C:0x22 //: 0x2C:0x00 //: 0x2C:0x01 //: 0x2C:0x02 //: diff --git a/transporthandler.cpp b/transporthandler.cpp index 25062ae..9ba2868 100644 --- a/transporthandler.cpp +++ b/transporthandler.cpp @@ -1719,6 +1719,28 @@ static int getSOLParameter(const std::string& property, ipmi::Value& value, return 0; } +constexpr const char* consoleInterface = "xyz.openbmc_project.console"; +constexpr const char* consolePath = "/xyz/openbmc_project/console"; +static int getSOLBaudRate(ipmi::Value& value) +{ + auto dbus = getSdBus(); + + try + { + value = + ipmi::getDbusProperty(*dbus, "xyz.openbmc_project.console", + consolePath, consoleInterface, "baudrate"); + } + catch (sdbusplus::exception_t&) + { + phosphor::logging::log( + "Error getting sol baud rate"); + return -1; + } + + return 0; +} + void initializeSOLInProgress() { ipmi::ChannelInfo chInfo; @@ -1913,6 +1935,171 @@ ipmi::RspType<> setSOLConfParams(ipmi::Context::ptr ctx, uint4_t chNum, return ipmi::responseSuccess(); } +static const constexpr uint8_t retryCountMask = 0x07; +static constexpr uint16_t ipmiStdPort = 623; +static constexpr uint8_t solParameterRevision = 0x11; +ipmi::RspType, std::optional> + getSOLConfParams(ipmi::Context::ptr ctx, uint4_t chNum, uint3_t reserved, + bool getParamRev, uint8_t paramSelector, + uint8_t setSelector, uint8_t blockSelector) +{ + ipmi::ChannelInfo chInfo; + uint8_t channelNum = ipmi::convertCurrentChannelNum( + static_cast(chNum), ctx->channel); + if (reserved != 0 || + (!ipmi::isValidChannel(static_cast(channelNum))) || + (ipmi::EChannelSessSupported::none == + ipmi::getChannelSessionSupport(static_cast(channelNum)))) + { + return ipmi::responseInvalidFieldRequest(); + } + ipmi_ret_t compCode = + ipmi::getChannelInfo(static_cast(channelNum), chInfo); + if (compCode != IPMI_CC_OK || + chInfo.mediumType != + static_cast(ipmi::EChannelMediumType::lan8032)) + { + return ipmi::responseInvalidFieldRequest(); + } + + if (getParamRev) + { + return ipmi::responseSuccess(solParameterRevision, std::nullopt, + std::nullopt); + } + + ipmi::Value value; + switch (static_cast(paramSelector)) + { + case sol::Parameter::progress: + { + if (getSOLParameter("Progress", value, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + return ipmi::responseSuccess( + solParameterRevision, std::get(value), std::nullopt); + } + case sol::Parameter::enable: + { + if (getSOLParameter("Enable", value, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + return ipmi::responseSuccess( + solParameterRevision, + static_cast(std::get(value)), std::nullopt); + } + case sol::Parameter::authentication: + { + uint8_t authentication = 0; + if (getSOLParameter("Privilege", value, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + authentication = (std::get(value) & 0x0f); + + if (getSOLParameter("ForceAuthentication", value, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + authentication |= + (static_cast(std::get(value)) << 6); + + if (getSOLParameter("ForceEncryption", value, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + authentication |= + (static_cast(std::get(value)) << 7); + return ipmi::responseSuccess(solParameterRevision, authentication, + std::nullopt); + } + case sol::Parameter::accumulate: + { + if (getSOLParameter("AccumulateIntervalMS", value, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + + ipmi::Value value1; + if (getSOLParameter("Threshold", value1, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + return ipmi::responseSuccess(solParameterRevision, + std::get(value), + std::get(value1)); + } + case sol::Parameter::retry: + { + if (getSOLParameter("RetryCount", value, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + + ipmi::Value value1; + if (getSOLParameter("RetryIntervalMS", value1, channelNum) < 0) + { + return ipmi::responseUnspecifiedError(); + } + return ipmi::responseSuccess( + solParameterRevision, std::get(value) & retryCountMask, + std::get(value1)); + } + case sol::Parameter::channel: + { + return ipmi::responseSuccess(solParameterRevision, channelNum, + std::nullopt); + } + case sol::Parameter::port: + { + uint16_t port = htole16(ipmiStdPort); + auto buffer = reinterpret_cast(&port); + return ipmi::responseSuccess(solParameterRevision, buffer[0], + buffer[1]); + } + case sol::Parameter::nvbitrate: + { + if (getSOLBaudRate(value) < 0) + { + return ipmi::responseUnspecifiedError(); + } + uint8_t bitRate = 0; + uint32_t* pBaudRate = std::get_if(&value); + if (!pBaudRate) + { + phosphor::logging::log( + "Failed to get valid baud rate from D-Bus interface"); + } + switch (*pBaudRate) + { + case 9600: + bitRate = 0x06; + break; + case 19200: + bitRate = 0x07; + break; + case 38400: + bitRate = 0x08; + break; + case 57600: + bitRate = 0x09; + break; + case 115200: + bitRate = 0x0a; + break; + default: + break; + } + return ipmi::responseSuccess(solParameterRevision, bitRate, + std::nullopt); + } + default: + return ipmi::responseParmNotSupported(); + } +} + void register_netfn_transport_functions() { // As this timer is only for transport handler @@ -1934,6 +2121,10 @@ void register_netfn_transport_functions() ipmi::transport::cmdSetSolConfigParameters, ipmi::Privilege::Admin, setSOLConfParams); + ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport, + ipmi::transport::cmdGetSolConfigParameters, + ipmi::Privilege::User, getSOLConfParams); + // Initialize dbus property progress to 0 every time sol manager restart. initializeSOLInProgress(); -- 2.7.4