blob: d65db12db6526aace0d347e10a81b1049d332154 [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 Mauery41ff9b52021-06-11 11:37:40 -070047 const std::vector<uint8_t>&, std::shared_ptr<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 Mauery2085ae02021-06-10 11:51:00 -0700219 private:
220 struct Private
221 {
222 };
223
Vernon Mauery9e801a22018-10-12 13:20:49 -0700224 public:
Vernon Mauery2085ae02021-06-10 11:51:00 -0700225 explicit Table(const Private&)
226 {
227 }
228 Table() = delete;
Vernon Mauery9e801a22018-10-12 13:20:49 -0700229 ~Table() = default;
230 // Command Table is a singleton so copy, copy-assignment, move and
231 // move assignment is deleted
232 Table(const Table&) = delete;
233 Table& operator=(const Table&) = delete;
234 Table(Table&&) = default;
235 Table& operator=(Table&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500236
Vernon Mauery2085ae02021-06-10 11:51:00 -0700237 /**
238 * @brief Get a reference to the singleton Table
239 *
240 * @return Table reference
241 */
242 static Table& get()
243 {
244 static std::shared_ptr<Table> ptr = nullptr;
245 if (!ptr)
246 {
247 ptr = std::make_shared<Table>(Private());
248 }
249 return *ptr;
250 }
251
Vernon Mauery9e801a22018-10-12 13:20:49 -0700252 using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;
Tom Joseph07181f52016-08-08 08:17:08 -0500253
Vernon Mauery9e801a22018-10-12 13:20:49 -0700254 /**
255 * @brief Register a command
256 *
257 * Register a command with the command table
258 *
259 * @param[in] inCommand - Command ID
260 * @param[in] entry - Command Entry
261 *
262 * @return: None
263 *
264 * @note: Duplicate registrations will be rejected.
265 *
266 */
267 void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry);
Tom Joseph07181f52016-08-08 08:17:08 -0500268
Vernon Mauery9e801a22018-10-12 13:20:49 -0700269 /**
270 * @brief Execute the command
271 *
272 * Execute the command for the corresponding CommandID
273 *
274 * @param[in] inCommand - Command ID to execute.
275 * @param[in] commandData - Request Data for the command
276 * @param[in] handler - Reference to the Message Handler
277 *
Vernon Mauery9e801a22018-10-12 13:20:49 -0700278 */
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800279 void executeCommand(uint32_t inCommand, std::vector<uint8_t>& commandData,
280 std::shared_ptr<message::Handler> handler);
Tom Joseph07181f52016-08-08 08:17:08 -0500281
Vernon Mauery9e801a22018-10-12 13:20:49 -0700282 private:
283 CommandTable commandTable;
Tom Joseph07181f52016-08-08 08:17:08 -0500284};
285
Vernon Mauery9e801a22018-10-12 13:20:49 -0700286} // namespace command