diff options
Diffstat (limited to 'user_channel/channelcommands.cpp')
-rw-r--r-- | user_channel/channelcommands.cpp | 591 |
1 files changed, 240 insertions, 351 deletions
diff --git a/user_channel/channelcommands.cpp b/user_channel/channelcommands.cpp index d1b275e..adf19d5 100644 --- a/user_channel/channelcommands.cpp +++ b/user_channel/channelcommands.cpp @@ -14,11 +14,10 @@ // limitations under the License. */ -#include "channelcommands.hpp" - #include "apphandler.hpp" #include "channel_layer.hpp" +#include <ipmid/api.hpp> #include <phosphor-logging/log.hpp> #include <regex> @@ -27,241 +26,99 @@ using namespace phosphor::logging; namespace ipmi { -/** @struct SetChannelAccessReq - * - * Structure for set channel access request command (refer spec sec 22.22) - */ -struct SetChannelAccessReq -{ -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t chNum : 4; - uint8_t reserved_1 : 4; - uint8_t accessMode : 3; - uint8_t usrAuthDisabled : 1; - uint8_t msgAuthDisabled : 1; - uint8_t alertDisabled : 1; - uint8_t accessSetMode : 2; - uint8_t privLimit : 4; - uint8_t reserved_2 : 2; - uint8_t privSetMode : 2; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved_1 : 4; - uint8_t chNum : 4; - uint8_t accessSetMode : 2; - uint8_t alertDisabled : 1; - uint8_t msgAuthDisabled : 1; - uint8_t usrAuthDisabled : 1; - uint8_t accessMode : 3; - uint8_t privSetMode : 2; - uint8_t reserved_2 : 2; - uint8_t privLimit : 4; -#endif - -} __attribute__((packed)); - -/** @struct GetChannelAccessReq - * - * Structure for get channel access request command (refer spec sec 22.23) - */ -struct GetChannelAccessReq -{ -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t chNum : 4; - uint8_t reserved_1 : 4; - uint8_t reserved_2 : 6; - uint8_t accessSetMode : 2; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved_1 : 4; - uint8_t chNum : 4; - uint8_t accessSetMode : 2; - uint8_t reserved_2 : 6; -#endif -} __attribute__((packed)); - -/** @struct GetChannelAccessResp +static constexpr const uint8_t ccActionNotSupportedForChannel = 0x82; + +/** @brief implements the set channel access command + * @ param ctx - context pointer + * @ param channel - channel number + * @ param reserved - skip 4 bits + * @ param accessMode - access mode for IPMI messaging + * @ param usrAuth - user level authentication (enable/disable) + * @ param msgAuth - per message authentication (enable/disable) + * @ param alertDisabled - PEF alerting (enable/disable) + * @ param chanAccess - channel access + * @ param channelPrivLimit - channel privilege limit + * @ param reserved - skip 3 bits + * @ param channelPrivMode - channel priviledge mode * - * Structure for get channel access response command (refer spec sec 22.23) - */ -struct GetChannelAccessResp + * @ returns IPMI completion code + **/ +RspType<> ipmiSetChannelAccess(Context::ptr ctx, uint4_t channel, + uint4_t reserved1, uint3_t accessMode, + bool usrAuth, bool msgAuth, bool alertDisabled, + uint2_t chanAccess, uint4_t channelPrivLimit, + uint2_t reserved2, uint2_t channelPrivMode) { -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t accessMode : 3; - uint8_t usrAuthDisabled : 1; - uint8_t msgAuthDisabled : 1; - uint8_t alertDisabled : 1; - uint8_t reserved_1 : 2; - uint8_t privLimit : 4; - uint8_t reserved_2 : 4; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved_1 : 2; - uint8_t alertDisabled : 1; - uint8_t msgAuthDisabled : 1; - uint8_t usrAuthDisabled : 1; - uint8_t accessMode : 3; - uint8_t reserved_2 : 4; - uint8_t privLimit : 4; -#endif -} __attribute__((packed)); - -/** @struct GetChannelInfoReq - * - * Structure for get channel info request command (refer spec sec 22.24) - */ -struct GetChannelInfoReq -{ -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t chNum : 4; - uint8_t reserved_1 : 4; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved_1 : 4; - uint8_t chNum : 4; -#endif -} __attribute__((packed)); - -/** @struct GetChannelInfoResp - * - * Structure for get channel info response command (refer spec sec 22.24) - */ -struct GetChannelInfoResp -{ -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t chNum : 4; - uint8_t reserved_1 : 4; - uint8_t mediumType : 7; - uint8_t reserved_2 : 1; - uint8_t msgProtType : 5; - uint8_t reserved_3 : 3; - uint8_t actSessCount : 6; - uint8_t sessType : 2; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved_1 : 4; - uint8_t chNum : 4; - uint8_t reserved_2 : 1; - uint8_t mediumType : 7; - uint8_t reserved_3 : 3; - uint8_t msgProtType : 5; - uint8_t sessType : 2; - uint8_t actSessCount : 6; -#endif - uint8_t vendorId[3]; - uint8_t auxChInfo[2]; -} __attribute__((packed)); - -/** @struct GetChannelPayloadSupportReq - * - * Structure for get channel payload support command request (refer spec - * sec 24.8) - */ -struct GetChannelPayloadSupportReq -{ -#if BYTE_ORDER == LITTLE_ENDIAN - uint8_t chNum : 4; - uint8_t reserved : 4; -#endif -#if BYTE_ORDER == BIG_ENDIAN - uint8_t reserved : 4; - uint8_t chNum : 4; -#endif -} __attribute__((packed)); - -/** @struct GetChannelPayloadSupportResp - * - * Structure for get channel payload support command response (refer spec - * sec 24.8) - */ -struct GetChannelPayloadSupportResp -{ - uint8_t stdPayloadType[2]; - uint8_t sessSetupPayloadType[2]; - uint8_t OEMPayloadType[2]; - uint8_t reserved[2]; -} __attribute__((packed)); - -ipmi_ret_t ipmiSetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_request_t request, - ipmi_response_t response, - ipmi_data_len_t data_len, - ipmi_context_t context) -{ - const SetChannelAccessReq* req = static_cast<SetChannelAccessReq*>(request); - size_t reqLength = *data_len; - - *data_len = 0; + const uint8_t chNum = + convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); - if (reqLength != sizeof(*req)) - { - log<level::DEBUG>("Set channel access - Invalid Length"); - return IPMI_CC_REQ_DATA_LEN_INVALID; - } - - uint8_t chNum = convertCurrentChannelNum(req->chNum); - if (!isValidChannel(chNum) || req->reserved_1 != 0 || req->reserved_2 != 0) + if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0) { log<level::DEBUG>("Set channel access - Invalid field in request"); - return IPMI_CC_INVALID_FIELD_REQUEST; + return responseInvalidFieldRequest(); } - if (EChannelSessSupported::none == getChannelSessionSupport(chNum)) + if (getChannelSessionSupport(chNum) == EChannelSessSupported::none) { log<level::DEBUG>("Set channel access - No support on channel"); - return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL; + return response(ccActionNotSupportedForChannel); } ChannelAccess chActData; ChannelAccess chNVData; uint8_t setActFlag = 0; uint8_t setNVFlag = 0; - ipmi_ret_t compCode = IPMI_CC_OK; + Cc compCode; - switch (req->accessSetMode) + // cannot static cast directly from uint2_t to enum; must go via int + uint8_t channelAccessAction = static_cast<uint8_t>(chanAccess); + switch (static_cast<EChannelActionType>(channelAccessAction)) { case doNotSet: - // Do nothing break; case nvData: - chNVData.accessMode = req->accessMode; - chNVData.userAuthDisabled = req->usrAuthDisabled; - chNVData.perMsgAuthDisabled = req->msgAuthDisabled; - chNVData.alertingDisabled = req->alertDisabled; + chNVData.accessMode = static_cast<uint8_t>(accessMode); + chNVData.userAuthDisabled = usrAuth; + chNVData.perMsgAuthDisabled = msgAuth; + chNVData.alertingDisabled = alertDisabled; setNVFlag |= (setAccessMode | setUserAuthEnabled | setMsgAuthEnabled | setAlertingEnabled); break; + case activeData: - chActData.accessMode = req->accessMode; - chActData.userAuthDisabled = req->usrAuthDisabled; - chActData.perMsgAuthDisabled = req->msgAuthDisabled; - chActData.alertingDisabled = req->alertDisabled; + chActData.accessMode = static_cast<uint8_t>(accessMode); + chActData.userAuthDisabled = usrAuth; + chActData.perMsgAuthDisabled = msgAuth; + chActData.alertingDisabled = alertDisabled; setActFlag |= (setAccessMode | setUserAuthEnabled | setMsgAuthEnabled | setAlertingEnabled); break; + case reserved: default: log<level::DEBUG>("Set channel access - Invalid access set mode"); - return IPMI_CC_INVALID_FIELD_REQUEST; + return responseInvalidFieldRequest(); } - switch (req->privSetMode) + // cannot static cast directly from uint2_t to enum; must go via int + uint8_t channelPrivAction = static_cast<uint8_t>(channelPrivMode); + switch (static_cast<EChannelActionType>(channelPrivAction)) { case doNotSet: - // Do nothing break; case nvData: - chNVData.privLimit = req->privLimit; + chNVData.privLimit = static_cast<uint8_t>(channelPrivLimit); setNVFlag |= setPrivLimit; break; case activeData: - chActData.privLimit = req->privLimit; + chActData.privLimit = static_cast<uint8_t>(channelPrivLimit); + setActFlag |= setPrivLimit; break; case reserved: default: log<level::DEBUG>("Set channel access - Invalid access priv mode"); - return IPMI_CC_INVALID_FIELD_REQUEST; + return responseInvalidFieldRequest(); } if (setNVFlag != 0) @@ -270,7 +127,7 @@ ipmi_ret_t ipmiSetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd, if (compCode != IPMI_CC_OK) { log<level::DEBUG>("Set channel access - Failed to set access data"); - return compCode; + return response(compCode); } } @@ -280,219 +137,250 @@ ipmi_ret_t ipmiSetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd, if (compCode != IPMI_CC_OK) { log<level::DEBUG>("Set channel access - Failed to set access data"); - return compCode; + return response(compCode); } } - return IPMI_CC_OK; + return responseSuccess(); } -ipmi_ret_t ipmiGetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_request_t request, - ipmi_response_t response, - ipmi_data_len_t data_len, - ipmi_context_t context) +/** @brief implements the get channel access command + * @ param ctx - context pointer + * @ param channel - channel number + * @ param reserved1 - skip 4 bits + * @ param reserved2 - skip 6 bits + * @ param accessMode - get access mode + * + * @returns ipmi completion code plus response data + * - accessMode - get access mode + * - usrAuthDisabled - user level authentication status + * - msgAuthDisabled - message level authentication status + * - alertDisabled - alerting status + * - reserved - skip 2 bits + * - privLimit - channel privilege limit + * - reserved - skip 4 bits + * */ +ipmi ::RspType<uint3_t, // access mode, + bool, // user authentication status, + bool, // message authentication status, + bool, // alerting status, + uint2_t, // reserved, + + uint4_t, // channel privilege, + uint4_t // reserved + > + ipmiGetChannelAccess(Context::ptr ctx, uint4_t channel, uint4_t reserved1, + uint6_t reserved2, uint2_t accessSetMode) { - const GetChannelAccessReq* req = static_cast<GetChannelAccessReq*>(request); - size_t reqLength = *data_len; - - *data_len = 0; - - if (reqLength != sizeof(*req)) - { - log<level::DEBUG>("Get channel access - Invalid Length"); - return IPMI_CC_REQ_DATA_LEN_INVALID; - } + const uint8_t chNum = + convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); - uint8_t chNum = convertCurrentChannelNum(req->chNum); - if (!isValidChannel(chNum) || req->reserved_1 != 0 || req->reserved_2 != 0) + if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0) { log<level::DEBUG>("Get channel access - Invalid field in request"); - return IPMI_CC_INVALID_FIELD_REQUEST; + return responseInvalidFieldRequest(); } - if ((req->accessSetMode == doNotSet) || (req->accessSetMode == reserved)) + if ((accessSetMode == doNotSet) || (accessSetMode == reserved)) { log<level::DEBUG>("Get channel access - Invalid Access mode"); - return IPMI_CC_INVALID_FIELD_REQUEST; + return responseInvalidFieldRequest(); } - if (EChannelSessSupported::none == getChannelSessionSupport(chNum)) + if (getChannelSessionSupport(chNum) == EChannelSessSupported::none) { log<level::DEBUG>("Get channel access - No support on channel"); - return IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL; + return response(ccActionNotSupportedForChannel); } - GetChannelAccessResp* resp = static_cast<GetChannelAccessResp*>(response); - - std::fill(reinterpret_cast<uint8_t*>(resp), - reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0); - ChannelAccess chAccess; - ipmi_ret_t compCode = IPMI_CC_OK; - if (req->accessSetMode == nvData) + Cc compCode; + + if (accessSetMode == nvData) { compCode = getChannelAccessPersistData(chNum, chAccess); } - else if (req->accessSetMode == activeData) + else if (accessSetMode == activeData) { compCode = getChannelAccessData(chNum, chAccess); } if (compCode != IPMI_CC_OK) { - return compCode; + return response(compCode); } - resp->accessMode = chAccess.accessMode; - resp->usrAuthDisabled = chAccess.userAuthDisabled; - resp->msgAuthDisabled = chAccess.perMsgAuthDisabled; - resp->alertDisabled = chAccess.alertingDisabled; - resp->privLimit = chAccess.privLimit; + constexpr uint2_t reservedOut1 = 0; + constexpr uint4_t reservedOut2 = 0; - *data_len = sizeof(*resp); - return IPMI_CC_OK; + return responseSuccess( + static_cast<uint3_t>(chAccess.accessMode), chAccess.userAuthDisabled, + chAccess.perMsgAuthDisabled, chAccess.alertingDisabled, reservedOut1, + static_cast<uint4_t>(chAccess.privLimit), reservedOut2); } -ipmi_ret_t ipmiGetChannelInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_request_t request, ipmi_response_t response, - ipmi_data_len_t data_len, ipmi_context_t context) +/** @brief implements the get channel info command + * @ param ctx - context pointer + * @ param channel - channel number + * @ param reserved - skip 4 bits + * + * @returns ipmi completion code plus response data + * - chNum - the channel number for this request + * - mediumType - see Table 6-3, Channel Medium Type Numbers + * - protocolType - Table 6-2, Channel Protocol Type Numbers + * - activeSessionCount - number of active sessions + * - sessionType - channel support for sessions + * - vendorId - vendor for this channel protocol (IPMI - 7154) + * - auxChInfo - auxiliary info for channel + * */ +RspType<uint4_t, // chNum + uint4_t, // reserved + uint7_t, // mediumType + bool, // reserved + uint5_t, // protocolType + uint3_t, // reserved + uint6_t, // activeSessionCount + uint2_t, // sessionType + uint24_t, // Vendor IANA + uint16_t // aux info + > + ipmiGetChannelInfo(Context::ptr ctx, uint4_t channel, uint4_t reserved) { - const GetChannelInfoReq* req = static_cast<GetChannelInfoReq*>(request); - size_t reqLength = *data_len; - - *data_len = 0; - - if (reqLength != sizeof(*req)) - { - log<level::DEBUG>("Get channel info - Invalid Length"); - return IPMI_CC_REQ_DATA_LEN_INVALID; - } - - uint8_t chNum = convertCurrentChannelNum(req->chNum); - if (!isValidChannel(chNum) || req->reserved_1 != 0) + uint8_t chNum = + convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); + if (!isValidChannel(chNum) || reserved) { - log<level::DEBUG>("Get channel info - Invalid field in request"); - return IPMI_CC_INVALID_FIELD_REQUEST; - } - - // Check the existance of device for session-less channels. - if ((EChannelSessSupported::none != getChannelSessionSupport(chNum)) && - (!(doesDeviceExist(chNum)))) - { - log<level::DEBUG>("Get channel info - Device not exist"); - return IPMI_CC_PARM_OUT_OF_RANGE; + log<level::DEBUG>("Get channel access - Invalid field in request"); + return responseInvalidFieldRequest(); } - GetChannelInfoResp* resp = static_cast<GetChannelInfoResp*>(response); - - std::fill(reinterpret_cast<uint8_t*>(resp), - reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0); - ChannelInfo chInfo; - ipmi_ret_t compCode = getChannelInfo(chNum, chInfo); - if (compCode != IPMI_CC_OK) + Cc compCode = getChannelInfo(chNum, chInfo); + if (compCode != ccSuccess) { - return compCode; + log<level::ERR>("Failed to get channel info", + entry("CHANNEL=%x", chNum), + entry("ERRNO=%x", compCode)); + return response(compCode); } - resp->chNum = chNum; - resp->mediumType = chInfo.mediumType; - resp->msgProtType = chInfo.protocolType; - resp->actSessCount = getChannelActiveSessions(chNum); - resp->sessType = chInfo.sessionSupported; - + constexpr uint4_t reserved1 = 0; + constexpr bool reserved2 = false; + constexpr uint3_t reserved3 = 0; + uint8_t mediumType = chInfo.mediumType; + uint8_t protocolType = chInfo.protocolType; + uint2_t sessionType = chInfo.sessionSupported; + uint6_t activeSessionCount = getChannelActiveSessions(chNum); // IPMI Spec: The IPMI Enterprise Number is: 7154 (decimal) - resp->vendorId[0] = 0xF2; - resp->vendorId[1] = 0x1B; - resp->vendorId[2] = 0x00; - - // Auxiliary Channel info - byte 1:2 - // TODO: For System Interface(0xF) and OEM channel types, this needs - // to be changed acoordingly. - // All other channel types, its reverved - resp->auxChInfo[0] = 0x00; - resp->auxChInfo[1] = 0x00; + constexpr uint24_t vendorId = 7154; + constexpr uint16_t auxChInfo = 0; - *data_len = sizeof(*resp); - - return IPMI_CC_OK; + return responseSuccess(chNum, reserved1, mediumType, reserved2, + protocolType, reserved3, activeSessionCount, + sessionType, vendorId, auxChInfo); } -ipmi_ret_t ipmiGetChannelPayloadSupport(ipmi_netfn_t netfn, ipmi_cmd_t cmd, - ipmi_request_t request, - ipmi_response_t response, - ipmi_data_len_t data_len, - ipmi_context_t context) +namespace { - const auto req = static_cast<GetChannelPayloadSupportReq*>(request); - size_t reqLength = *data_len; - - *data_len = 0; - - if (reqLength != sizeof(*req)) - { - log<level::DEBUG>("Get channel payload - Invalid Length"); - return IPMI_CC_REQ_DATA_LEN_INVALID; - } +constexpr uint16_t standardPayloadBit(PayloadType p) +{ + return (1 << static_cast<size_t>(p)); +} - uint8_t chNum = convertCurrentChannelNum(req->chNum); - if (!isValidChannel(chNum) || req->reserved != 0) - { - log<level::DEBUG>("Get channel payload - Invalid field in request"); - return IPMI_CC_INVALID_FIELD_REQUEST; - } +constexpr uint16_t sessionPayloadBit(PayloadType p) +{ + constexpr size_t sessionShift = + static_cast<size_t>(PayloadType::OPEN_SESSION_REQUEST); + return ((1 << static_cast<size_t>(p)) >> sessionShift); +} +} // namespace - // Not supported on sessionless channels. - if (EChannelSessSupported::none == getChannelSessionSupport(chNum)) +/** @brief implements get channel payload support command + * @ param ctx - ipmi context pointer + * @ param chNum - channel number + * @ param reserved - skip 4 bits + * + * @ returns IPMI completion code plus response data + * - stdPayloadType - bitmask of supported standard payload types + * - sessSetupPayloadType - bitmask of supported session setup payload types + * - OEMPayloadType - bitmask of supported OEM payload types + * - reserved - 2 bytes of 0 + **/ +RspType<uint16_t, // stdPayloadType + uint16_t, // sessSetupPayloadType + uint16_t, // OEMPayloadType + uint16_t // reserved + > + ipmiGetChannelPayloadSupport(Context::ptr ctx, uint4_t channel, + uint4_t reserved) +{ + uint8_t chNum = + convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel); + if (!isValidChannel(chNum) || reserved) { - log<level::DEBUG>("Get channel payload - Sessionless Channel"); - return IPMI_CC_INVALID_FIELD_REQUEST; + log<level::DEBUG>("Get channel access - Invalid field in request"); + return responseInvalidFieldRequest(); } // Session support is available in active LAN channels. - if ((EChannelSessSupported::none != getChannelSessionSupport(chNum)) && - (!(doesDeviceExist(chNum)))) + if ((getChannelSessionSupport(chNum) == EChannelSessSupported::none) || + !(doesDeviceExist(chNum))) { log<level::DEBUG>("Get channel payload - Device not exist"); - return IPMI_CC_INVALID_FIELD_REQUEST; + return responseInvalidFieldRequest(); } - auto resp = static_cast<GetChannelPayloadSupportResp*>(response); + constexpr uint16_t stdPayloadType = standardPayloadBit(PayloadType::IPMI) | + standardPayloadBit(PayloadType::SOL); + constexpr uint16_t sessSetupPayloadType = + sessionPayloadBit(PayloadType::OPEN_SESSION_REQUEST) | + sessionPayloadBit(PayloadType::OPEN_SESSION_RESPONSE) | + sessionPayloadBit(PayloadType::RAKP1) | + sessionPayloadBit(PayloadType::RAKP2) | + sessionPayloadBit(PayloadType::RAKP3) | + sessionPayloadBit(PayloadType::RAKP4); + constexpr uint16_t OEMPayloadType = 0; + constexpr uint16_t rspRsvd = 0; + return responseSuccess(stdPayloadType, sessSetupPayloadType, OEMPayloadType, + rspRsvd); +} - std::fill(reinterpret_cast<uint8_t*>(resp), - reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0); +/** @brief implements the get channel payload version command + * @param ctx - IPMI context pointer (for channel) + * @param chNum - channel number to get info about + * @param reserved - skip 4 bits + * @param payloadTypeNum - to get payload type info - // TODO: Hard coding for now. - // Mapping PayloadTypes to 'GetChannelPayloadSupportResp' fields: - // -------------------------------------------------------------- - // Mask all except least 3 significant bits to get a value in the range of - // 0-7. This value maps to the bit position of given payload type in 'resp' - // fields. + * @returns IPMI completion code plus response data + * - formatVersion - BCD encoded format version info + */ - static constexpr uint8_t payloadByteMask = 0x07; - static constexpr uint8_t stdPayloadTypeIPMI = - 1 << (static_cast<uint8_t>(PayloadType::IPMI) & payloadByteMask); - static constexpr uint8_t stdPayloadTypeSOL = - 1 << (static_cast<uint8_t>(PayloadType::SOL) & payloadByteMask); +RspType<uint8_t> // formatVersion + ipmiGetChannelPayloadVersion(Context::ptr ctx, uint4_t chNum, + uint4_t reserved, uint8_t payloadTypeNum) +{ + uint8_t channel = + convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel); - static constexpr uint8_t sessPayloadTypeOpenReq = - 1 << (static_cast<uint8_t>(PayloadType::OPEN_SESSION_REQUEST) & - payloadByteMask); - static constexpr uint8_t sessPayloadTypeRAKP1 = - 1 << (static_cast<uint8_t>(PayloadType::RAKP1) & payloadByteMask); - static constexpr uint8_t sessPayloadTypeRAKP3 = - 1 << (static_cast<uint8_t>(PayloadType::RAKP3) & payloadByteMask); + if (reserved || !isValidChannel(channel) || + (getChannelSessionSupport(channel)) == EChannelSessSupported::none) + { + return responseInvalidFieldRequest(); + } + + if (!isValidPayloadType(static_cast<PayloadType>(payloadTypeNum))) + { + log<level::ERR>("Channel payload version - Payload type unavailable"); - resp->stdPayloadType[0] = stdPayloadTypeIPMI | stdPayloadTypeSOL; - // RMCP+ Open Session request, RAKP Message1 and RAKP Message3. - resp->sessSetupPayloadType[0] = - sessPayloadTypeOpenReq | sessPayloadTypeRAKP1 | sessPayloadTypeRAKP3; + constexpr uint8_t payloadTypeNotSupported = 0x80; + return response(payloadTypeNotSupported); + } - *data_len = sizeof(*resp); + // BCD encoded version representation - 1.0 + constexpr uint8_t formatVersion = 0x10; - return IPMI_CC_OK; + return responseSuccess(formatVersion); } void registerChannelFunctions() __attribute__((constructor)); @@ -500,19 +388,20 @@ void registerChannelFunctions() { ipmiChannelInit(); - ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_CHANNEL_ACCESS, NULL, - ipmiSetChannelAccess, PRIVILEGE_ADMIN); + registerHandler(prioOpenBmcBase, netFnApp, app::cmdSetChannelAccess, + Privilege::Admin, ipmiSetChannelAccess); - ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_ACCESS, NULL, - ipmiGetChannelAccess, PRIVILEGE_USER); + registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelAccess, + Privilege::User, ipmiGetChannelAccess); - ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_INFO, NULL, - ipmiGetChannelInfo, PRIVILEGE_USER); + registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelInfoCommand, + Privilege::User, ipmiGetChannelInfo); - ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_PAYLOAD_SUPPORT, - NULL, ipmiGetChannelPayloadSupport, PRIVILEGE_USER); + registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadSupport, + Privilege::User, ipmiGetChannelPayloadSupport); - return; + registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadVersion, + Privilege::User, ipmiGetChannelPayloadVersion); } } // namespace ipmi |