user_channel: Get Channel Payload Support command refactor
Update the get channel payload support command to use the new IPMI API.
This simplifies the code as well as adds support for the special IPMI
channel 0x0e.
Tested: ipmitool -I lanplus -H ... -U ... raw 6 0x4e 0xe
03 00 3f 00 00 00 00 00
ipmitool -I lanplus -H ... -U ... raw 6 0x4e 1
03 00 3f 00 00 00 00 00
Change-Id: I8b67d6f79c40299b4b653212a2f1f9d0c1a9087c
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/user_channel/channelcommands.cpp b/user_channel/channelcommands.cpp
index 9c633ec..2e1b196 100644
--- a/user_channel/channelcommands.cpp
+++ b/user_channel/channelcommands.cpp
@@ -14,8 +14,6 @@
// limitations under the License.
*/
-#include "channelcommands.hpp"
-
#include "apphandler.hpp"
#include "channel_layer.hpp"
@@ -28,36 +26,6 @@
namespace ipmi
{
-/** @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));
-
/** @brief implements the set channel access command
* @ param ctx - context pointer
* @ param channel - channel number
@@ -311,79 +279,69 @@
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;
+constexpr uint16_t standardPayloadBit(PayloadType p)
+{
+ return (1 << static_cast<size_t>(p));
+}
- *data_len = 0;
+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
- if (reqLength != sizeof(*req))
+/** @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 - Invalid Length");
- return IPMI_CC_REQ_DATA_LEN_INVALID;
- }
-
- 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;
- }
-
- // Not supported on sessionless channels.
- if (EChannelSessSupported::none == getChannelSessionSupport(chNum))
- {
- 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);
-
- std::fill(reinterpret_cast<uint8_t*>(resp),
- reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
-
- // 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.
-
- 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);
-
- 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);
-
- resp->stdPayloadType[0] = stdPayloadTypeIPMI | stdPayloadTypeSOL;
- // RMCP+ Open Session request, RAKP Message1 and RAKP Message3.
- resp->sessSetupPayloadType[0] =
- sessPayloadTypeOpenReq | sessPayloadTypeRAKP1 | sessPayloadTypeRAKP3;
-
- *data_len = sizeof(*resp);
-
- return IPMI_CC_OK;
+ 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);
}
void registerChannelFunctions() __attribute__((constructor));
@@ -400,10 +358,8 @@
registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelInfoCommand,
Privilege::User, ipmiGetChannelInfo);
- ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_PAYLOAD_SUPPORT,
- NULL, ipmiGetChannelPayloadSupport, PRIVILEGE_USER);
-
- return;
+ registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadSupport,
+ Privilege::User, ipmiGetChannelPayloadSupport);
}
} // namespace ipmi
diff --git a/user_channel/channelcommands.hpp b/user_channel/channelcommands.hpp
deleted file mode 100644
index abcead6..0000000
--- a/user_channel/channelcommands.hpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-// Copyright (c) 2018 Intel Corporation
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-*/
-
-#pragma once
-#include <cstdint>
-
-namespace ipmi
-{
-
-/**
- * @enum IPMI commands for channel command NETFN:APP
- */
-enum ipmi_netfn_channel_cmds
-{
- IPMI_CMD_SET_CHANNEL_ACCESS = 0x40,
- IPMI_CMD_GET_CHANNEL_ACCESS = 0x41,
- IPMI_CMD_GET_CHANNEL_INFO = 0x42,
- IPMI_CMD_GET_CHANNEL_PAYLOAD_SUPPORT = 0x4E,
-};
-
-void registerChannelFunctions();
-} // namespace ipmi