blob: e882300e0111fbad05b171e3a4c2ad9eb8beb126 [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
William A. Kennington III4f09eae2019-02-12 17:10:35 -08005#include <ipmid/api.h>
Vernon Mauery9e801a22018-10-12 13:20:49 -07006
Andrew Geissler9d9b7632020-05-17 09:18:05 -05007#include <cstddef>
Vernon Mauery9e801a22018-10-12 13:20:49 -07008#include <functional>
9#include <map>
Tom Joseph07181f52016-08-08 08:17:08 -050010
11namespace command
12{
13
Vernon Mauery66501642018-07-30 09:07:10 -070014struct CommandID
Tom Joseph07181f52016-08-08 08:17:08 -050015{
Vernon Mauery66501642018-07-30 09:07:10 -070016 static constexpr size_t lunBits = 2;
17 CommandID(uint32_t command) : command(command)
Tom Joseph07181f52016-08-08 08:17:08 -050018 {
Vernon Mauery66501642018-07-30 09:07:10 -070019 }
Tom Joseph07181f52016-08-08 08:17:08 -050020
Vernon Mauery66501642018-07-30 09:07:10 -070021 uint8_t netFnLun() const
22 {
23 return static_cast<uint8_t>(command >> CHAR_BIT);
24 }
25 uint8_t netFn() const
26 {
27 return netFnLun() >> lunBits;
28 }
29 uint8_t lun() const
30 {
31 return netFnLun() & ((1 << (lunBits + 1)) - 1);
32 }
33 uint8_t cmd() const
34 {
35 return static_cast<uint8_t>(command);
36 }
37 uint32_t command;
38};
Tom Joseph07181f52016-08-08 08:17:08 -050039
Tom Joseph3563f8f2017-05-08 15:42:54 +053040/**
Tom Joseph07181f52016-08-08 08:17:08 -050041 * CommandFunctor is the functor register for commands defined in
42 * phosphor-net-ipmid. This would take the request part of the command as a
43 * vector and a reference to the message handler. The response part of the
44 * command is returned as a vector.
45 */
46using CommandFunctor = std::function<std::vector<uint8_t>(
Vernon Mauery9e801a22018-10-12 13:20:49 -070047 const std::vector<uint8_t>&, const message::Handler&)>;
Tom Joseph07181f52016-08-08 08:17:08 -050048
Tom Joseph3563f8f2017-05-08 15:42:54 +053049/**
Tom Joseph07181f52016-08-08 08:17:08 -050050 * @struct CmdDetails
51 *
52 * Command details is used to register commands supported in phosphor-net-ipmid.
53 */
54struct CmdDetails
55{
56 CommandID command;
57 CommandFunctor functor;
58 session::Privilege privilege;
59 bool sessionless;
60};
61
Tom Joseph3563f8f2017-05-08 15:42:54 +053062/**
Tom Joseph07181f52016-08-08 08:17:08 -050063 * @enum NetFns
64 *
65 * A field that identifies the functional class of the message. The Network
66 * Function clusters IPMI commands into different sets.
67 */
68enum class NetFns
69{
Vernon Mauery9e801a22018-10-12 13:20:49 -070070 CHASSIS = (0x00 << 10),
71 CHASSIS_RESP = (0x01 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050072
Vernon Mauery9e801a22018-10-12 13:20:49 -070073 BRIDGE = (0x02 << 10),
74 BRIDGE_RESP = (0x03 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050075
Vernon Mauery9e801a22018-10-12 13:20:49 -070076 SENSOR = (0x04 << 10),
77 SENSOR_RESP = (0x05 << 10),
78 EVENT = (0x04 << 10),
79 EVENT_RESP = (0x05 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050080
Vernon Mauery9e801a22018-10-12 13:20:49 -070081 APP = (0x06 << 10),
82 APP_RESP = (0x07 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050083
Vernon Mauery9e801a22018-10-12 13:20:49 -070084 FIRMWARE = (0x08 << 10),
85 FIRMWARE_RESP = (0x09 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050086
Vernon Mauery9e801a22018-10-12 13:20:49 -070087 STORAGE = (0x0A << 10),
88 STORAGE_RESP = (0x0B << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050089
Vernon Mauery9e801a22018-10-12 13:20:49 -070090 TRANSPORT = (0x0C << 10),
91 TRANSPORT_RESP = (0x0D << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050092
93 //>>
Vernon Mauery9e801a22018-10-12 13:20:49 -070094 RESERVED_START = (0x0E << 10),
95 RESERVED_END = (0x2B << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050096 //<<
97
Vernon Mauery9e801a22018-10-12 13:20:49 -070098 GROUP_EXTN = (0x2C << 10),
99 GROUP_EXTN_RESP = (0x2D << 10),
Tom Joseph07181f52016-08-08 08:17:08 -0500100
Vernon Mauery9e801a22018-10-12 13:20:49 -0700101 OEM = (0x2E << 10),
102 OEM_RESP = (0x2F << 10),
Tom Joseph07181f52016-08-08 08:17:08 -0500103};
104
Tom Joseph3563f8f2017-05-08 15:42:54 +0530105/**
Tom Joseph07181f52016-08-08 08:17:08 -0500106 * @class Entry
107 *
108 * This is the base class for registering IPMI commands. There are two ways of
109 * registering commands to phosphor-net-ipmid, the session related commands and
110 * provider commands
111 *
112 * Every commands has a privilege level which mentions the minimum session
113 * privilege level needed to execute the command
114 */
115
116class Entry
117{
118
Vernon Mauery9e801a22018-10-12 13:20:49 -0700119 public:
120 Entry(CommandID command, session::Privilege privilege) :
121 command(command), privilege(privilege)
122 {
123 }
Tom Joseph07181f52016-08-08 08:17:08 -0500124
Vernon Mauery9e801a22018-10-12 13:20:49 -0700125 /**
126 * @brief Execute the command
127 *
128 * Execute the command
129 *
130 * @param[in] commandData - Request Data for the command
131 * @param[in] handler - Reference to the Message Handler
132 *
133 * @return Response data for the command
134 */
135 virtual std::vector<uint8_t>
136 executeCommand(std::vector<uint8_t>& commandData,
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800137 std::shared_ptr<message::Handler> handler) = 0;
Tom Joseph07181f52016-08-08 08:17:08 -0500138
Vernon Mauery9e801a22018-10-12 13:20:49 -0700139 auto getCommand() const
140 {
141 return command;
142 }
Tom Joseph07181f52016-08-08 08:17:08 -0500143
Vernon Mauery9e801a22018-10-12 13:20:49 -0700144 auto getPrivilege() const
145 {
146 return privilege;
147 }
Tom Joseph07181f52016-08-08 08:17:08 -0500148
Vernon Mauery9e801a22018-10-12 13:20:49 -0700149 virtual ~Entry() = default;
150 Entry(const Entry&) = default;
151 Entry& operator=(const Entry&) = default;
152 Entry(Entry&&) = default;
153 Entry& operator=(Entry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500154
Vernon Mauery9e801a22018-10-12 13:20:49 -0700155 protected:
156 CommandID command;
Tom Joseph07181f52016-08-08 08:17:08 -0500157
Vernon Mauery9e801a22018-10-12 13:20:49 -0700158 // Specifies the minimum privilege level required to execute this command
159 session::Privilege privilege;
Tom Joseph07181f52016-08-08 08:17:08 -0500160};
161
Tom Joseph3563f8f2017-05-08 15:42:54 +0530162/**
Tom Joseph07181f52016-08-08 08:17:08 -0500163 * @class NetIpmidEntry
164 *
165 * NetIpmidEntry is used to register commands that are consumed only in
166 * phosphor-net-ipmid. The RAKP commands, session commands and user management
167 * commands are examples of this.
168 *
169 * There are certain IPMI commands that can be executed before session can be
170 * established like Get System GUID, Get Channel Authentication Capabilities
171 * and RAKP commands.
172 */
Vernon Mauery9e801a22018-10-12 13:20:49 -0700173class NetIpmidEntry final : public Entry
Tom Joseph07181f52016-08-08 08:17:08 -0500174{
175
Vernon Mauery9e801a22018-10-12 13:20:49 -0700176 public:
177 NetIpmidEntry(CommandID command, CommandFunctor functor,
178 session::Privilege privilege, bool sessionless) :
179 Entry(command, privilege),
180 functor(functor), sessionless(sessionless)
181 {
182 }
Tom Joseph07181f52016-08-08 08:17:08 -0500183
Vernon Mauery9e801a22018-10-12 13:20:49 -0700184 /**
185 * @brief Execute the command
186 *
187 * Execute the command
188 *
189 * @param[in] commandData - Request Data for the command
190 * @param[in] handler - Reference to the Message Handler
191 *
192 * @return Response data for the command
193 */
194 std::vector<uint8_t>
195 executeCommand(std::vector<uint8_t>& commandData,
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800196 std::shared_ptr<message::Handler> handler) override;
Tom Joseph07181f52016-08-08 08:17:08 -0500197
Vernon Mauery9e801a22018-10-12 13:20:49 -0700198 virtual ~NetIpmidEntry() = default;
199 NetIpmidEntry(const NetIpmidEntry&) = default;
200 NetIpmidEntry& operator=(const NetIpmidEntry&) = default;
201 NetIpmidEntry(NetIpmidEntry&&) = default;
202 NetIpmidEntry& operator=(NetIpmidEntry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500203
Vernon Mauery9e801a22018-10-12 13:20:49 -0700204 private:
205 CommandFunctor functor;
Tom Joseph07181f52016-08-08 08:17:08 -0500206
Vernon Mauery9e801a22018-10-12 13:20:49 -0700207 bool sessionless;
Tom Joseph07181f52016-08-08 08:17:08 -0500208};
209
Tom Joseph3563f8f2017-05-08 15:42:54 +0530210/**
Tom Joseph07181f52016-08-08 08:17:08 -0500211 * @class Table
212 *
213 * Table keeps the IPMI command entries as a sorted associative container with
214 * Command ID as the unique key. It has interfaces for registering commands
215 * and executing a command.
216 */
217class Table
218{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700219 public:
220 Table() = default;
221 ~Table() = default;
222 // Command Table is a singleton so copy, copy-assignment, move and
223 // move assignment is deleted
224 Table(const Table&) = delete;
225 Table& operator=(const Table&) = delete;
226 Table(Table&&) = default;
227 Table& operator=(Table&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500228
Vernon Mauery9e801a22018-10-12 13:20:49 -0700229 using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;
Tom Joseph07181f52016-08-08 08:17:08 -0500230
Vernon Mauery9e801a22018-10-12 13:20:49 -0700231 /**
232 * @brief Register a command
233 *
234 * Register a command with the command table
235 *
236 * @param[in] inCommand - Command ID
237 * @param[in] entry - Command Entry
238 *
239 * @return: None
240 *
241 * @note: Duplicate registrations will be rejected.
242 *
243 */
244 void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry);
Tom Joseph07181f52016-08-08 08:17:08 -0500245
Vernon Mauery9e801a22018-10-12 13:20:49 -0700246 /**
247 * @brief Execute the command
248 *
249 * Execute the command for the corresponding CommandID
250 *
251 * @param[in] inCommand - Command ID to execute.
252 * @param[in] commandData - Request Data for the command
253 * @param[in] handler - Reference to the Message Handler
254 *
Vernon Mauery9e801a22018-10-12 13:20:49 -0700255 */
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800256 void executeCommand(uint32_t inCommand, std::vector<uint8_t>& commandData,
257 std::shared_ptr<message::Handler> handler);
Tom Joseph07181f52016-08-08 08:17:08 -0500258
Vernon Mauery9e801a22018-10-12 13:20:49 -0700259 private:
260 CommandTable commandTable;
Tom Joseph07181f52016-08-08 08:17:08 -0500261};
262
Vernon Mauery9e801a22018-10-12 13:20:49 -0700263} // namespace command