1 /* 2 * Copyright © 2018 Intel Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 #pragma once 18 19 #define ALLOW_DEPRECATED_API 1 20 21 #include <ipmid/iana.hpp> 22 #include <ipmid/message/types.hpp> 23 #include <optional> 24 #include <sdbusplus/asio/connection.hpp> 25 #include <sdbusplus/asio/object_server.hpp> 26 27 /* NOTE: 28 * 29 * This is intended for native C++ use. For the legacy C api, include 30 * ipmid-api.h for a reduced functionality. Note that the C api is now marked 31 * as deprecated and will be removed once all the internal users of it have 32 * been updated to use the new C++ api. 33 */ 34 35 namespace ipmi 36 { 37 38 using Iana = oem::Number; 39 40 using Group = uint8_t; 41 constexpr Group groupPICMG = 0x00; 42 constexpr Group groupDMTG = 0x01; 43 constexpr Group groupSSI = 0x02; 44 constexpr Group groupVSO = 0x03; 45 constexpr Group groupDCMI = 0xDC; 46 47 /* 48 * Set the priority as the lowest number that is necessary so 49 * it is possible that others can override it if desired. 50 * This may be linked to what level of integration the handler 51 * is being created at. 52 */ 53 constexpr int prioOpenBmcBase = 10; 54 constexpr int prioOemBase = 20; 55 constexpr int prioOdmBase = 30; 56 constexpr int prioCustomBase = 40; 57 constexpr int prioMax = 50; 58 59 /* 60 * Channel IDs pulled from the IPMI 2.0 specification 61 */ 62 constexpr int channelPrimaryIpmb = 0x00; 63 // 0x01-0x0B Implementation specific 64 // Implementation specific channel numbers are specified 65 // by a configuration file external to ipmid 66 // 0x0C-0x0D reserved 67 constexpr int channelCurrentIface = 0x0E; // 'Present I/F' 68 constexpr int channelSystemIface = 0x0F; 69 70 /* 71 * Specifies the minimum privilege level required to execute the command 72 * This means the command can be executed at a given privilege level or higher 73 * privilege level. Those commands which can be executed via system interface 74 * only should use SYSTEM_INTERFACE 75 */ 76 enum class Privilege : uint8_t 77 { 78 None = 0x00, 79 Callback, 80 User, 81 Operator, 82 Admin, 83 Oem, 84 }; 85 86 // IPMI Net Function number as specified by IPMI V2.0 spec. 87 using NetFn = uint8_t; 88 89 // IPMI Command for a Net Function number as specified by IPMI V2.0 spec. 90 using Cmd = uint8_t; 91 92 // ipmi function return the status code 93 using Cc = uint8_t; 94 95 // These are the command network functions, the response 96 // network functions are the function + 1. So to determine 97 // the proper network function which issued the command 98 // associated with a response, subtract 1. 99 // Note: these will be left shifted when combined with the LUN 100 constexpr NetFn netFnChassis = 0x00; 101 constexpr NetFn netFnBridge = 0x02; 102 constexpr NetFn netFnSensor = 0x04; 103 constexpr NetFn netFnApp = 0x06; 104 constexpr NetFn netFnFirmware = 0x08; 105 constexpr NetFn netFnStorage = 0x0A; 106 constexpr NetFn netFnTransport = 0x0C; 107 // reserved 0Eh..28h 108 constexpr NetFn netFnGroup = 0x2C; 109 constexpr NetFn netFnOem = 0x2E; 110 constexpr NetFn netFnOemOne = 0x30; 111 constexpr NetFn netFnOemTwo = 0x32; 112 constexpr NetFn netFnOemThree = 0x34; 113 constexpr NetFn netFnOemFour = 0x36; 114 constexpr NetFn netFnOemFive = 0x38; 115 constexpr NetFn netFnOemSix = 0x3A; 116 constexpr NetFn netFnOemSeven = 0x3C; 117 constexpr NetFn netFnOemEight = 0x3E; 118 119 // IPMI commands for net functions. Callbacks using this should be careful to 120 // parse arguments to the sub-functions and can take advantage of the built-in 121 // message handling mechanism to create custom routing 122 constexpr Cmd cmdWildcard = 0xFF; 123 124 // IPMI standard completion codes specified by the IPMI V2.0 spec. 125 // 126 // This might have been an enum class, but that would make it hard for 127 // OEM- and command-specific completion codes to be added elsewhere. 128 // 129 // Custom completion codes can be defined in individual modules for 130 // command specific errors in the 0x80-0xBE range 131 // 132 // Alternately, OEM completion codes are in the 0x01-0x7E range 133 constexpr Cc ccSuccess = 0x00; 134 constexpr Cc ccBusy = 0xC0; 135 constexpr Cc ccInvalidCommand = 0xC1; 136 constexpr Cc ccInvalidCommandOnLun = 0xC2; 137 constexpr Cc ccTimeout = 0xC2; 138 constexpr Cc ccOutOfSpace = 0xC2; 139 constexpr Cc ccInvalidReservationId = 0xC5; 140 constexpr Cc ccReqDataTruncated = 0xC6; 141 constexpr Cc ccReqDataLenInvalid = 0xC7; 142 constexpr Cc ccReqDataLenExceeded = 0xC8; 143 constexpr Cc ccParmOutOfRange = 0xC9; 144 constexpr Cc ccRetBytesUnavailable = 0xCA; 145 constexpr Cc ccSensorInvalid = 0xCB; 146 constexpr Cc ccInvalidFieldRequest = 0xCC; 147 constexpr Cc ccIllegalCommand = 0xCD; 148 constexpr Cc ccResponseError = 0xCE; 149 constexpr Cc ccDuplicateRequest = 0xCF; 150 constexpr Cc ccCmdFailSdrMode = 0xD0; 151 constexpr Cc ccCmdFailFwUpdMode = 0xD1; 152 constexpr Cc ccCmdFailInitAgent = 0xD2; 153 constexpr Cc ccDestinationUnavailable = 0xD3; 154 constexpr Cc ccInsufficientPrivilege = 0xD4; 155 constexpr Cc ccCommandNotAvailable = 0xD5; 156 constexpr Cc ccCommandDisabled = 0xD6; 157 constexpr Cc ccUnspecifiedError = 0xFF; 158 159 /* ipmi often has two return types: 160 * 1. Failure: CC is non-zero; no trailing data 161 * 2. Success: CC is zero; trailing data (usually a fixed type) 162 * 163 * using ipmi::response(cc, ...), it will automatically always pack 164 * the correct type for the response without having to explicitly type out all 165 * the parameters that the function would return. 166 * 167 * To enable this feature, you just define the ipmi function as returning an 168 * ipmi::RspType which has the optional trailing data built in, with your types 169 * defined as parameters. 170 */ 171 172 template <typename... RetTypes> 173 using RspType = std::tuple<ipmi::Cc, std::optional<std::tuple<RetTypes...>>>; 174 175 /** 176 * @brief helper function to create an IPMI response tuple 177 * 178 * IPMI handlers all return a tuple with two parts: a completion code and an 179 * optional tuple containing the rest of the data to return. This helper 180 * function makes it easier by constructing that out of an arbitrary number of 181 * arguments. 182 * 183 * @param cc - the completion code for the response 184 * @param args... - the optional list of values to return 185 * 186 * @return a standard IPMI return type (as described above) 187 */ 188 template <typename... Args> 189 static inline auto response(ipmi::Cc cc, Args&&... args) 190 { 191 return std::make_tuple(cc, std::make_optional(std::make_tuple(args...))); 192 } 193 static inline auto response(ipmi::Cc cc) 194 { 195 return std::make_tuple(cc, std::nullopt); 196 } 197 198 /** 199 * @brief helper function to create an IPMI success response tuple 200 * 201 * IPMI handlers all return a tuple with two parts: a completion code and an 202 * optional tuple containing the rest of the data to return. This helper 203 * function makes it easier by constructing that out of an arbitrary number of 204 * arguments. Because it is a success response, this automatically packs 205 * the completion code, without needing to explicitly pass it in. 206 * 207 * @param args... - the optional list of values to return 208 * 209 * @return a standard IPMI return type (as described above) 210 */ 211 template <typename... Args> 212 static inline auto responseSuccess(Args&&... args) 213 { 214 return std::make_tuple(ipmi::ccSuccess, 215 std::make_optional(std::make_tuple(args...))); 216 } 217 static inline auto responseSuccess() 218 { 219 return std::make_tuple(ipmi::ccSuccess, std::nullopt); 220 } 221 222 } // namespace ipmi 223 224 // any client can interact with the main asio service 225 std::shared_ptr<boost::asio::io_service> getIoService(); 226 227 // any client can interact with the main sdbus 228 std::shared_ptr<sdbusplus::asio::connection> getSdBus(); 229 230 /** 231 * @brief post some work to the async exection queue 232 * 233 * The IPMI daemon runs an async exection queue; this allows any function to 234 * pass in work to be executed in that context 235 * 236 * @tparam WorkFn - a function of type void(void) 237 * @param work - the callback function to be executed 238 */ 239 template <typename WorkFn> 240 static inline void post_work(WorkFn work) 241 { 242 getIoService()->post(std::forward<WorkFn>(work)); 243 } 244