blob: 295c659ca9eb4211d17f64e558da15656fc1b0fa [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)
George Liubc8958f2022-07-04 09:29:49 +080018 {}
Tom Joseph07181f52016-08-08 08:17:08 -050019
Vernon Mauery66501642018-07-30 09:07:10 -070020 uint8_t netFnLun() const
21 {
22 return static_cast<uint8_t>(command >> CHAR_BIT);
23 }
24 uint8_t netFn() const
25 {
26 return netFnLun() >> lunBits;
27 }
28 uint8_t lun() const
29 {
30 return netFnLun() & ((1 << (lunBits + 1)) - 1);
31 }
32 uint8_t cmd() const
33 {
34 return static_cast<uint8_t>(command);
35 }
36 uint32_t command;
37};
Tom Joseph07181f52016-08-08 08:17:08 -050038
Tom Joseph3563f8f2017-05-08 15:42:54 +053039/**
Tom Joseph07181f52016-08-08 08:17:08 -050040 * CommandFunctor is the functor register for commands defined in
41 * phosphor-net-ipmid. This would take the request part of the command as a
42 * vector and a reference to the message handler. The response part of the
43 * command is returned as a vector.
44 */
45using CommandFunctor = std::function<std::vector<uint8_t>(
Vernon Mauery41ff9b52021-06-11 11:37:40 -070046 const std::vector<uint8_t>&, std::shared_ptr<message::Handler>&)>;
Tom Joseph07181f52016-08-08 08:17:08 -050047
Tom Joseph3563f8f2017-05-08 15:42:54 +053048/**
Tom Joseph07181f52016-08-08 08:17:08 -050049 * @struct CmdDetails
50 *
51 * Command details is used to register commands supported in phosphor-net-ipmid.
52 */
53struct CmdDetails
54{
55 CommandID command;
56 CommandFunctor functor;
57 session::Privilege privilege;
58 bool sessionless;
59};
60
Tom Joseph3563f8f2017-05-08 15:42:54 +053061/**
Tom Joseph07181f52016-08-08 08:17:08 -050062 * @enum NetFns
63 *
64 * A field that identifies the functional class of the message. The Network
65 * Function clusters IPMI commands into different sets.
66 */
67enum class NetFns
68{
Vernon Mauery9e801a22018-10-12 13:20:49 -070069 CHASSIS = (0x00 << 10),
70 CHASSIS_RESP = (0x01 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050071
Vernon Mauery9e801a22018-10-12 13:20:49 -070072 BRIDGE = (0x02 << 10),
73 BRIDGE_RESP = (0x03 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050074
Vernon Mauery9e801a22018-10-12 13:20:49 -070075 SENSOR = (0x04 << 10),
76 SENSOR_RESP = (0x05 << 10),
77 EVENT = (0x04 << 10),
78 EVENT_RESP = (0x05 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050079
Vernon Mauery9e801a22018-10-12 13:20:49 -070080 APP = (0x06 << 10),
81 APP_RESP = (0x07 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050082
Vernon Mauery9e801a22018-10-12 13:20:49 -070083 FIRMWARE = (0x08 << 10),
84 FIRMWARE_RESP = (0x09 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050085
Vernon Mauery9e801a22018-10-12 13:20:49 -070086 STORAGE = (0x0A << 10),
87 STORAGE_RESP = (0x0B << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050088
Vernon Mauery9e801a22018-10-12 13:20:49 -070089 TRANSPORT = (0x0C << 10),
90 TRANSPORT_RESP = (0x0D << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050091
92 //>>
Vernon Mauery9e801a22018-10-12 13:20:49 -070093 RESERVED_START = (0x0E << 10),
94 RESERVED_END = (0x2B << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050095 //<<
96
Vernon Mauery9e801a22018-10-12 13:20:49 -070097 GROUP_EXTN = (0x2C << 10),
98 GROUP_EXTN_RESP = (0x2D << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050099
Vernon Mauery9e801a22018-10-12 13:20:49 -0700100 OEM = (0x2E << 10),
101 OEM_RESP = (0x2F << 10),
Tom Joseph07181f52016-08-08 08:17:08 -0500102};
103
Tom Joseph3563f8f2017-05-08 15:42:54 +0530104/**
Tom Joseph07181f52016-08-08 08:17:08 -0500105 * @class Entry
106 *
107 * This is the base class for registering IPMI commands. There are two ways of
108 * registering commands to phosphor-net-ipmid, the session related commands and
109 * provider commands
110 *
111 * Every commands has a privilege level which mentions the minimum session
112 * privilege level needed to execute the command
113 */
114
115class Entry
116{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700117 public:
118 Entry(CommandID command, session::Privilege privilege) :
119 command(command), privilege(privilege)
George Liubc8958f2022-07-04 09:29:49 +0800120 {}
Tom Joseph07181f52016-08-08 08:17:08 -0500121
Vernon Mauery9e801a22018-10-12 13:20:49 -0700122 /**
123 * @brief Execute the command
124 *
125 * Execute the command
126 *
127 * @param[in] commandData - Request Data for the command
128 * @param[in] handler - Reference to the Message Handler
129 *
130 * @return Response data for the command
131 */
132 virtual std::vector<uint8_t>
133 executeCommand(std::vector<uint8_t>& commandData,
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800134 std::shared_ptr<message::Handler> handler) = 0;
Tom Joseph07181f52016-08-08 08:17:08 -0500135
Vernon Mauery9e801a22018-10-12 13:20:49 -0700136 auto getCommand() const
137 {
138 return command;
139 }
Tom Joseph07181f52016-08-08 08:17:08 -0500140
Vernon Mauery9e801a22018-10-12 13:20:49 -0700141 auto getPrivilege() const
142 {
143 return privilege;
144 }
Tom Joseph07181f52016-08-08 08:17:08 -0500145
Vernon Mauery9e801a22018-10-12 13:20:49 -0700146 virtual ~Entry() = default;
147 Entry(const Entry&) = default;
148 Entry& operator=(const Entry&) = default;
149 Entry(Entry&&) = default;
150 Entry& operator=(Entry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500151
Vernon Mauery9e801a22018-10-12 13:20:49 -0700152 protected:
153 CommandID command;
Tom Joseph07181f52016-08-08 08:17:08 -0500154
Vernon Mauery9e801a22018-10-12 13:20:49 -0700155 // Specifies the minimum privilege level required to execute this command
156 session::Privilege privilege;
Tom Joseph07181f52016-08-08 08:17:08 -0500157};
158
Tom Joseph3563f8f2017-05-08 15:42:54 +0530159/**
Tom Joseph07181f52016-08-08 08:17:08 -0500160 * @class NetIpmidEntry
161 *
162 * NetIpmidEntry is used to register commands that are consumed only in
163 * phosphor-net-ipmid. The RAKP commands, session commands and user management
164 * commands are examples of this.
165 *
166 * There are certain IPMI commands that can be executed before session can be
167 * established like Get System GUID, Get Channel Authentication Capabilities
168 * and RAKP commands.
169 */
Vernon Mauery9e801a22018-10-12 13:20:49 -0700170class NetIpmidEntry final : public Entry
Tom Joseph07181f52016-08-08 08:17:08 -0500171{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700172 public:
173 NetIpmidEntry(CommandID command, CommandFunctor functor,
174 session::Privilege privilege, bool sessionless) :
175 Entry(command, privilege),
176 functor(functor), sessionless(sessionless)
George Liubc8958f2022-07-04 09:29:49 +0800177 {}
Tom Joseph07181f52016-08-08 08:17:08 -0500178
Vernon Mauery9e801a22018-10-12 13:20:49 -0700179 /**
180 * @brief Execute the command
181 *
182 * Execute the command
183 *
184 * @param[in] commandData - Request Data for the command
185 * @param[in] handler - Reference to the Message Handler
186 *
187 * @return Response data for the command
188 */
189 std::vector<uint8_t>
190 executeCommand(std::vector<uint8_t>& commandData,
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800191 std::shared_ptr<message::Handler> handler) override;
Tom Joseph07181f52016-08-08 08:17:08 -0500192
Vernon Mauery9e801a22018-10-12 13:20:49 -0700193 virtual ~NetIpmidEntry() = default;
194 NetIpmidEntry(const NetIpmidEntry&) = default;
195 NetIpmidEntry& operator=(const NetIpmidEntry&) = default;
196 NetIpmidEntry(NetIpmidEntry&&) = default;
197 NetIpmidEntry& operator=(NetIpmidEntry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500198
Vernon Mauery9e801a22018-10-12 13:20:49 -0700199 private:
200 CommandFunctor functor;
Tom Joseph07181f52016-08-08 08:17:08 -0500201
Vernon Mauery9e801a22018-10-12 13:20:49 -0700202 bool sessionless;
Tom Joseph07181f52016-08-08 08:17:08 -0500203};
204
Tom Joseph3563f8f2017-05-08 15:42:54 +0530205/**
Tom Joseph07181f52016-08-08 08:17:08 -0500206 * @class Table
207 *
208 * Table keeps the IPMI command entries as a sorted associative container with
209 * Command ID as the unique key. It has interfaces for registering commands
210 * and executing a command.
211 */
212class Table
213{
Vernon Mauery2085ae02021-06-10 11:51:00 -0700214 private:
215 struct Private
George Liubc8958f2022-07-04 09:29:49 +0800216 {};
Vernon Mauery2085ae02021-06-10 11:51:00 -0700217
Vernon Mauery9e801a22018-10-12 13:20:49 -0700218 public:
Vernon Mauery2085ae02021-06-10 11:51:00 -0700219 explicit Table(const Private&)
George Liubc8958f2022-07-04 09:29:49 +0800220 {}
Vernon Mauery2085ae02021-06-10 11:51:00 -0700221 Table() = delete;
Vernon Mauery9e801a22018-10-12 13:20:49 -0700222 ~Table() = default;
223 // Command Table is a singleton so copy, copy-assignment, move and
224 // move assignment is deleted
225 Table(const Table&) = delete;
226 Table& operator=(const Table&) = delete;
227 Table(Table&&) = default;
228 Table& operator=(Table&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500229
Vernon Mauery2085ae02021-06-10 11:51:00 -0700230 /**
231 * @brief Get a reference to the singleton Table
232 *
233 * @return Table reference
234 */
235 static Table& get()
236 {
237 static std::shared_ptr<Table> ptr = nullptr;
238 if (!ptr)
239 {
240 ptr = std::make_shared<Table>(Private());
241 }
242 return *ptr;
243 }
244
Vernon Mauery9e801a22018-10-12 13:20:49 -0700245 using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;
Tom Joseph07181f52016-08-08 08:17:08 -0500246
Vernon Mauery9e801a22018-10-12 13:20:49 -0700247 /**
248 * @brief Register a command
249 *
250 * Register a command with the command table
251 *
252 * @param[in] inCommand - Command ID
253 * @param[in] entry - Command Entry
254 *
255 * @return: None
256 *
257 * @note: Duplicate registrations will be rejected.
258 *
259 */
260 void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry);
Tom Joseph07181f52016-08-08 08:17:08 -0500261
Vernon Mauery9e801a22018-10-12 13:20:49 -0700262 /**
263 * @brief Execute the command
264 *
265 * Execute the command for the corresponding CommandID
266 *
267 * @param[in] inCommand - Command ID to execute.
268 * @param[in] commandData - Request Data for the command
269 * @param[in] handler - Reference to the Message Handler
270 *
Vernon Mauery9e801a22018-10-12 13:20:49 -0700271 */
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800272 void executeCommand(uint32_t inCommand, std::vector<uint8_t>& commandData,
273 std::shared_ptr<message::Handler> handler);
Tom Joseph07181f52016-08-08 08:17:08 -0500274
Vernon Mauery9e801a22018-10-12 13:20:49 -0700275 private:
276 CommandTable commandTable;
Tom Joseph07181f52016-08-08 08:17:08 -0500277};
278
Vernon Mauery9e801a22018-10-12 13:20:49 -0700279} // namespace command