diff options
author | Vernon Mauery <vernon.mauery@linux.intel.com> | 2018-10-08 12:05:16 -0700 |
---|---|---|
committer | Vernon Mauery <vernon.mauery@linux.intel.com> | 2019-02-25 14:27:21 -0800 |
commit | e7329c71f3d22e010c38a7f738e81ab78330038e (patch) | |
tree | 8cb355cbde96d7a341f1c707c7f0e8c334f88e58 /include/ipmid/api.hpp | |
parent | 1bb0c7fc55b21bb40b7afb567f2f938f15411ca1 (diff) | |
download | phosphor-host-ipmid-e7329c71f3d22e010c38a7f738e81ab78330038e.tar.gz phosphor-host-ipmid-e7329c71f3d22e010c38a7f738e81ab78330038e.zip |
ipmid: Compiler-generated unpacking and packing of messages
handler.hpp has the templated wrapping bits for ipmi command handler
callbacks implemented.
message.hpp has the serialization/deserialization of the ipmi data
stream into packed tuples for functions.
message/pack.hpp and message/unpack.hpp contain the actual serialization
and deserialization of types.
Change-Id: If997f8768c8488ab6ac022526a5ef9a1bce57fcb
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
Diffstat (limited to 'include/ipmid/api.hpp')
-rw-r--r-- | include/ipmid/api.hpp | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/include/ipmid/api.hpp b/include/ipmid/api.hpp new file mode 100644 index 0000000..47dc04d --- /dev/null +++ b/include/ipmid/api.hpp @@ -0,0 +1,243 @@ +/* + * Copyright © 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 + +#define ALLOW_DEPRECATED_API 1 + +#include <ipmid/iana.hpp> +#include <ipmid/message/types.hpp> +#include <optional> +#include <sdbusplus/asio/connection.hpp> +#include <sdbusplus/asio/object_server.hpp> + +/* NOTE: + * + * This is intended for native C++ use. For the legacy C api, include + * ipmid-api.h for a reduced functionality. Note that the C api is now marked + * as deprecated and will be removed once all the internal users of it have + * been updated to use the new C++ api. + */ + +namespace ipmi +{ + +using Iana = oem::Number; + +using Group = uint8_t; +constexpr Group groupPICMG = 0x00; +constexpr Group groupDMTG = 0x01; +constexpr Group groupSSI = 0x02; +constexpr Group groupVSO = 0x03; +constexpr Group groupDCMI = 0xDC; + +/* + * Set the priority as the lowest number that is necessary so + * it is possible that others can override it if desired. + * This may be linked to what level of integration the handler + * is being created at. + */ +constexpr int prioOpenBmcBase = 10; +constexpr int prioOemBase = 20; +constexpr int prioOdmBase = 30; +constexpr int prioCustomBase = 40; +constexpr int prioMax = 50; + +/* + * Channel IDs pulled from the IPMI 2.0 specification + */ +constexpr int channelPrimaryIpmb = 0x00; +// 0x01-0x0B Implementation specific +// Implementation specific channel numbers are specified +// by a configuration file external to ipmid +// 0x0C-0x0D reserved +constexpr int channelCurrentIface = 0x0E; // 'Present I/F' +constexpr int channelSystemIface = 0x0F; + +/* + * Specifies the minimum privilege level required to execute the command + * This means the command can be executed at a given privilege level or higher + * privilege level. Those commands which can be executed via system interface + * only should use SYSTEM_INTERFACE + */ +enum class Privilege : uint8_t +{ + None = 0x00, + Callback, + User, + Operator, + Admin, + Oem, +}; + +// IPMI Net Function number as specified by IPMI V2.0 spec. +using NetFn = uint8_t; + +// IPMI Command for a Net Function number as specified by IPMI V2.0 spec. +using Cmd = uint8_t; + +// ipmi function return the status code +using Cc = uint8_t; + +// These are the command network functions, the response +// network functions are the function + 1. So to determine +// the proper network function which issued the command +// associated with a response, subtract 1. +// Note: these will be left shifted when combined with the LUN +constexpr NetFn netFnChassis = 0x00; +constexpr NetFn netFnBridge = 0x02; +constexpr NetFn netFnSensor = 0x04; +constexpr NetFn netFnApp = 0x06; +constexpr NetFn netFnFirmware = 0x08; +constexpr NetFn netFnStorage = 0x0A; +constexpr NetFn netFnTransport = 0x0C; +// reserved 0Eh..28h +constexpr NetFn netFnGroup = 0x2C; +constexpr NetFn netFnOem = 0x2E; +constexpr NetFn netFnOemOne = 0x30; +constexpr NetFn netFnOemTwo = 0x32; +constexpr NetFn netFnOemThree = 0x34; +constexpr NetFn netFnOemFour = 0x36; +constexpr NetFn netFnOemFive = 0x38; +constexpr NetFn netFnOemSix = 0x3A; +constexpr NetFn netFnOemSeven = 0x3C; +constexpr NetFn netFnOemEight = 0x3E; + +// IPMI commands for net functions. Callbacks using this should be careful to +// parse arguments to the sub-functions and can take advantage of the built-in +// message handling mechanism to create custom routing +constexpr Cmd cmdWildcard = 0xFF; + +// IPMI standard completion codes specified by the IPMI V2.0 spec. +// +// This might have been an enum class, but that would make it hard for +// OEM- and command-specific completion codes to be added elsewhere. +// +// Custom completion codes can be defined in individual modules for +// command specific errors in the 0x80-0xBE range +// +// Alternately, OEM completion codes are in the 0x01-0x7E range +constexpr Cc ccSuccess = 0x00; +constexpr Cc ccBusy = 0xC0; +constexpr Cc ccInvalidCommand = 0xC1; +constexpr Cc ccInvalidCommandOnLun = 0xC2; +constexpr Cc ccTimeout = 0xC2; +constexpr Cc ccOutOfSpace = 0xC2; +constexpr Cc ccInvalidReservationId = 0xC5; +constexpr Cc ccReqDataTruncated = 0xC6; +constexpr Cc ccReqDataLenInvalid = 0xC7; +constexpr Cc ccReqDataLenExceeded = 0xC8; +constexpr Cc ccParmOutOfRange = 0xC9; +constexpr Cc ccRetBytesUnavailable = 0xCA; +constexpr Cc ccSensorInvalid = 0xCB; +constexpr Cc ccInvalidFieldRequest = 0xCC; +constexpr Cc ccIllegalCommand = 0xCD; +constexpr Cc ccResponseError = 0xCE; +constexpr Cc ccDuplicateRequest = 0xCF; +constexpr Cc ccCmdFailSdrMode = 0xD0; +constexpr Cc ccCmdFailFwUpdMode = 0xD1; +constexpr Cc ccCmdFailInitAgent = 0xD2; +constexpr Cc ccDestinationUnavailable = 0xD3; +constexpr Cc ccInsufficientPrivilege = 0xD4; +constexpr Cc ccCommandNotAvailable = 0xD5; +constexpr Cc ccCommandDisabled = 0xD6; +constexpr Cc ccUnspecifiedError = 0xFF; + +/* ipmi often has two return types: + * 1. Failure: CC is non-zero; no trailing data + * 2. Success: CC is zero; trailing data (usually a fixed type) + * + * using ipmi::response(cc, ...), it will automatically always pack + * the correct type for the response without having to explicitly type out all + * the parameters that the function would return. + * + * To enable this feature, you just define the ipmi function as returning an + * ipmi::RspType which has the optional trailing data built in, with your types + * defined as parameters. + */ + +template <typename... RetTypes> +using RspType = std::tuple<ipmi::Cc, std::optional<std::tuple<RetTypes...>>>; + +/** + * @brief helper function to create an IPMI response tuple + * + * IPMI handlers all return a tuple with two parts: a completion code and an + * optional tuple containing the rest of the data to return. This helper + * function makes it easier by constructing that out of an arbitrary number of + * arguments. + * + * @param cc - the completion code for the response + * @param args... - the optional list of values to return + * + * @return a standard IPMI return type (as described above) + */ +template <typename... Args> +static inline auto response(ipmi::Cc cc, Args&&... args) +{ + return std::make_tuple(cc, std::make_optional(std::make_tuple(args...))); +} +static inline auto response(ipmi::Cc cc) +{ + return std::make_tuple(cc, std::nullopt); +} + +/** + * @brief helper function to create an IPMI success response tuple + * + * IPMI handlers all return a tuple with two parts: a completion code and an + * optional tuple containing the rest of the data to return. This helper + * function makes it easier by constructing that out of an arbitrary number of + * arguments. Because it is a success response, this automatically packs + * the completion code, without needing to explicitly pass it in. + * + * @param args... - the optional list of values to return + * + * @return a standard IPMI return type (as described above) + */ +template <typename... Args> +static inline auto responseSuccess(Args&&... args) +{ + return std::make_tuple(ipmi::ccSuccess, + std::make_optional(std::make_tuple(args...))); +} +static inline auto responseSuccess() +{ + return std::make_tuple(ipmi::ccSuccess, std::nullopt); +} + +} // namespace ipmi + +// any client can interact with the main asio service +std::shared_ptr<boost::asio::io_service> getIoService(); + +// any client can interact with the main sdbus +std::shared_ptr<sdbusplus::asio::connection> getSdBus(); + +/** + * @brief post some work to the async exection queue + * + * The IPMI daemon runs an async exection queue; this allows any function to + * pass in work to be executed in that context + * + * @tparam WorkFn - a function of type void(void) + * @param work - the callback function to be executed + */ +template <typename WorkFn> +static inline void post_work(WorkFn work) +{ + getIoService()->post(std::forward<WorkFn>(work)); +} |