blob: ba7eaa5ab55cc7d823ae22e0165ddc7ea082f256 [file] [log] [blame]
Tom Joseph07181f52016-08-08 08:17:08 -05001#pragma once
2
Vernon Mauery9e801a22018-10-12 13:20:49 -07003#include "message_handler.hpp"
Tom Joseph07181f52016-08-08 08:17:08 -05004
Tom606e8cb2016-12-02 13:36:14 +05305#include <host-ipmid/ipmid-api.h>
Vernon Mauery9e801a22018-10-12 13:20:49 -07006
7#include <functional>
8#include <map>
Tom Joseph07181f52016-08-08 08:17:08 -05009
10namespace command
11{
12
13union CommandID
14{
15 uint32_t command;
16
17 uint8_t reserved;
18 message::PayloadType payloadType;
19
20 union
21 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070022 uint8_t netFn : 6;
23 uint8_t lun : 2;
Tom Joseph07181f52016-08-08 08:17:08 -050024
25 uint8_t netFnLun;
26 } NetFnLun;
27
28 uint8_t cmd;
29} __attribute__((packed));
30
Tom Joseph3563f8f2017-05-08 15:42:54 +053031/**
Tom Joseph07181f52016-08-08 08:17:08 -050032 * CommandFunctor is the functor register for commands defined in
33 * phosphor-net-ipmid. This would take the request part of the command as a
34 * vector and a reference to the message handler. The response part of the
35 * command is returned as a vector.
36 */
37using CommandFunctor = std::function<std::vector<uint8_t>(
Vernon Mauery9e801a22018-10-12 13:20:49 -070038 const std::vector<uint8_t>&, const message::Handler&)>;
Tom Joseph07181f52016-08-08 08:17:08 -050039
Tom Joseph3563f8f2017-05-08 15:42:54 +053040/**
Tom Joseph07181f52016-08-08 08:17:08 -050041 * @struct CmdDetails
42 *
43 * Command details is used to register commands supported in phosphor-net-ipmid.
44 */
45struct CmdDetails
46{
47 CommandID command;
48 CommandFunctor functor;
49 session::Privilege privilege;
50 bool sessionless;
51};
52
Tom Joseph3563f8f2017-05-08 15:42:54 +053053/**
Tom Joseph07181f52016-08-08 08:17:08 -050054 * @enum NetFns
55 *
56 * A field that identifies the functional class of the message. The Network
57 * Function clusters IPMI commands into different sets.
58 */
59enum class NetFns
60{
Vernon Mauery9e801a22018-10-12 13:20:49 -070061 CHASSIS = (0x00 << 10),
62 CHASSIS_RESP = (0x01 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050063
Vernon Mauery9e801a22018-10-12 13:20:49 -070064 BRIDGE = (0x02 << 10),
65 BRIDGE_RESP = (0x03 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050066
Vernon Mauery9e801a22018-10-12 13:20:49 -070067 SENSOR = (0x04 << 10),
68 SENSOR_RESP = (0x05 << 10),
69 EVENT = (0x04 << 10),
70 EVENT_RESP = (0x05 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050071
Vernon Mauery9e801a22018-10-12 13:20:49 -070072 APP = (0x06 << 10),
73 APP_RESP = (0x07 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050074
Vernon Mauery9e801a22018-10-12 13:20:49 -070075 FIRMWARE = (0x08 << 10),
76 FIRMWARE_RESP = (0x09 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050077
Vernon Mauery9e801a22018-10-12 13:20:49 -070078 STORAGE = (0x0A << 10),
79 STORAGE_RESP = (0x0B << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050080
Vernon Mauery9e801a22018-10-12 13:20:49 -070081 TRANSPORT = (0x0C << 10),
82 TRANSPORT_RESP = (0x0D << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050083
84 //>>
Vernon Mauery9e801a22018-10-12 13:20:49 -070085 RESERVED_START = (0x0E << 10),
86 RESERVED_END = (0x2B << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050087 //<<
88
Vernon Mauery9e801a22018-10-12 13:20:49 -070089 GROUP_EXTN = (0x2C << 10),
90 GROUP_EXTN_RESP = (0x2D << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050091
Vernon Mauery9e801a22018-10-12 13:20:49 -070092 OEM = (0x2E << 10),
93 OEM_RESP = (0x2F << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050094};
95
Tom Joseph3563f8f2017-05-08 15:42:54 +053096/**
Tom Joseph07181f52016-08-08 08:17:08 -050097 * @class Entry
98 *
99 * This is the base class for registering IPMI commands. There are two ways of
100 * registering commands to phosphor-net-ipmid, the session related commands and
101 * provider commands
102 *
103 * Every commands has a privilege level which mentions the minimum session
104 * privilege level needed to execute the command
105 */
106
107class Entry
108{
109
Vernon Mauery9e801a22018-10-12 13:20:49 -0700110 public:
111 Entry(CommandID command, session::Privilege privilege) :
112 command(command), privilege(privilege)
113 {
114 }
Tom Joseph07181f52016-08-08 08:17:08 -0500115
Vernon Mauery9e801a22018-10-12 13:20:49 -0700116 /**
117 * @brief Execute the command
118 *
119 * Execute the command
120 *
121 * @param[in] commandData - Request Data for the command
122 * @param[in] handler - Reference to the Message Handler
123 *
124 * @return Response data for the command
125 */
126 virtual std::vector<uint8_t>
127 executeCommand(std::vector<uint8_t>& commandData,
128 const message::Handler& handler) = 0;
Tom Joseph07181f52016-08-08 08:17:08 -0500129
Vernon Mauery9e801a22018-10-12 13:20:49 -0700130 auto getCommand() const
131 {
132 return command;
133 }
Tom Joseph07181f52016-08-08 08:17:08 -0500134
Vernon Mauery9e801a22018-10-12 13:20:49 -0700135 auto getPrivilege() const
136 {
137 return privilege;
138 }
Tom Joseph07181f52016-08-08 08:17:08 -0500139
Vernon Mauery9e801a22018-10-12 13:20:49 -0700140 virtual ~Entry() = default;
141 Entry(const Entry&) = default;
142 Entry& operator=(const Entry&) = default;
143 Entry(Entry&&) = default;
144 Entry& operator=(Entry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500145
Vernon Mauery9e801a22018-10-12 13:20:49 -0700146 protected:
147 CommandID command;
Tom Joseph07181f52016-08-08 08:17:08 -0500148
Vernon Mauery9e801a22018-10-12 13:20:49 -0700149 // Specifies the minimum privilege level required to execute this command
150 session::Privilege privilege;
Tom Joseph07181f52016-08-08 08:17:08 -0500151};
152
Tom Joseph3563f8f2017-05-08 15:42:54 +0530153/**
Tom Joseph07181f52016-08-08 08:17:08 -0500154 * @class NetIpmidEntry
155 *
156 * NetIpmidEntry is used to register commands that are consumed only in
157 * phosphor-net-ipmid. The RAKP commands, session commands and user management
158 * commands are examples of this.
159 *
160 * There are certain IPMI commands that can be executed before session can be
161 * established like Get System GUID, Get Channel Authentication Capabilities
162 * and RAKP commands.
163 */
Vernon Mauery9e801a22018-10-12 13:20:49 -0700164class NetIpmidEntry final : public Entry
Tom Joseph07181f52016-08-08 08:17:08 -0500165{
166
Vernon Mauery9e801a22018-10-12 13:20:49 -0700167 public:
168 NetIpmidEntry(CommandID command, CommandFunctor functor,
169 session::Privilege privilege, bool sessionless) :
170 Entry(command, privilege),
171 functor(functor), sessionless(sessionless)
172 {
173 }
Tom Joseph07181f52016-08-08 08:17:08 -0500174
Vernon Mauery9e801a22018-10-12 13:20:49 -0700175 /**
176 * @brief Execute the command
177 *
178 * Execute the command
179 *
180 * @param[in] commandData - Request Data for the command
181 * @param[in] handler - Reference to the Message Handler
182 *
183 * @return Response data for the command
184 */
185 std::vector<uint8_t>
186 executeCommand(std::vector<uint8_t>& commandData,
187 const message::Handler& handler) override;
Tom Joseph07181f52016-08-08 08:17:08 -0500188
Vernon Mauery9e801a22018-10-12 13:20:49 -0700189 virtual ~NetIpmidEntry() = default;
190 NetIpmidEntry(const NetIpmidEntry&) = default;
191 NetIpmidEntry& operator=(const NetIpmidEntry&) = default;
192 NetIpmidEntry(NetIpmidEntry&&) = default;
193 NetIpmidEntry& operator=(NetIpmidEntry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500194
Vernon Mauery9e801a22018-10-12 13:20:49 -0700195 private:
196 CommandFunctor functor;
Tom Joseph07181f52016-08-08 08:17:08 -0500197
Vernon Mauery9e801a22018-10-12 13:20:49 -0700198 bool sessionless;
Tom Joseph07181f52016-08-08 08:17:08 -0500199};
200
Tom Joseph3563f8f2017-05-08 15:42:54 +0530201/**
Tom606e8cb2016-12-02 13:36:14 +0530202 * @class ProviderIpmidEntry
203 *
204 * ProviderIpmidEntry is used to register commands to the Command Table, that
205 * are registered by IPMI provider libraries.
206 *
207 */
Vernon Mauery9e801a22018-10-12 13:20:49 -0700208class ProviderIpmidEntry final : public Entry
Tom606e8cb2016-12-02 13:36:14 +0530209{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700210 public:
211 ProviderIpmidEntry(CommandID command, ipmid_callback_t functor,
212 session::Privilege privilege) :
213 Entry(command, privilege),
214 functor(functor)
215 {
216 }
Tom606e8cb2016-12-02 13:36:14 +0530217
Vernon Mauery9e801a22018-10-12 13:20:49 -0700218 /**
219 * @brief Execute the command
220 *
221 * Execute the callback handler
222 *
223 * @param[in] commandData - Request Data for the command
224 * @param[in] handler - Reference to the Message Handler
225 *
226 * @return Response data for the command
227 */
228 std::vector<uint8_t>
229 executeCommand(std::vector<uint8_t>& commandData,
230 const message::Handler& handler) override;
Tom606e8cb2016-12-02 13:36:14 +0530231
Vernon Mauery9e801a22018-10-12 13:20:49 -0700232 virtual ~ProviderIpmidEntry() = default;
233 ProviderIpmidEntry(const ProviderIpmidEntry&) = default;
234 ProviderIpmidEntry& operator=(const ProviderIpmidEntry&) = default;
235 ProviderIpmidEntry(ProviderIpmidEntry&&) = default;
236 ProviderIpmidEntry& operator=(ProviderIpmidEntry&&) = default;
Tom606e8cb2016-12-02 13:36:14 +0530237
Vernon Mauery9e801a22018-10-12 13:20:49 -0700238 private:
239 ipmid_callback_t functor;
Tom606e8cb2016-12-02 13:36:14 +0530240};
241
Tom Joseph3563f8f2017-05-08 15:42:54 +0530242/**
Tom Joseph07181f52016-08-08 08:17:08 -0500243 * @class Table
244 *
245 * Table keeps the IPMI command entries as a sorted associative container with
246 * Command ID as the unique key. It has interfaces for registering commands
247 * and executing a command.
248 */
249class Table
250{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700251 public:
252 Table() = default;
253 ~Table() = default;
254 // Command Table is a singleton so copy, copy-assignment, move and
255 // move assignment is deleted
256 Table(const Table&) = delete;
257 Table& operator=(const Table&) = delete;
258 Table(Table&&) = default;
259 Table& operator=(Table&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500260
Vernon Mauery9e801a22018-10-12 13:20:49 -0700261 using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;
Tom Joseph07181f52016-08-08 08:17:08 -0500262
Vernon Mauery9e801a22018-10-12 13:20:49 -0700263 /**
264 * @brief Register a command
265 *
266 * Register a command with the command table
267 *
268 * @param[in] inCommand - Command ID
269 * @param[in] entry - Command Entry
270 *
271 * @return: None
272 *
273 * @note: Duplicate registrations will be rejected.
274 *
275 */
276 void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry);
Tom Joseph07181f52016-08-08 08:17:08 -0500277
Vernon Mauery9e801a22018-10-12 13:20:49 -0700278 /**
279 * @brief Execute the command
280 *
281 * Execute the command for the corresponding CommandID
282 *
283 * @param[in] inCommand - Command ID to execute.
284 * @param[in] commandData - Request Data for the command
285 * @param[in] handler - Reference to the Message Handler
286 *
287 * @return Response data for the command
288 */
289 std::vector<uint8_t> executeCommand(uint32_t inCommand,
290 std::vector<uint8_t>& commandData,
291 const message::Handler& handler);
Tom Joseph07181f52016-08-08 08:17:08 -0500292
Vernon Mauery9e801a22018-10-12 13:20:49 -0700293 private:
294 CommandTable commandTable;
Tom Joseph07181f52016-08-08 08:17:08 -0500295};
296
Vernon Mauery9e801a22018-10-12 13:20:49 -0700297} // namespace command