blob: 7e9df055eb654d77834ce0650e09043c3eb00909 [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
7#include <functional>
8#include <map>
Tom Joseph07181f52016-08-08 08:17:08 -05009
10namespace command
11{
12
Vernon Mauery66501642018-07-30 09:07:10 -070013struct CommandID
Tom Joseph07181f52016-08-08 08:17:08 -050014{
Vernon Mauery66501642018-07-30 09:07:10 -070015 static constexpr size_t lunBits = 2;
16 CommandID(uint32_t command) : command(command)
Tom Joseph07181f52016-08-08 08:17:08 -050017 {
Vernon Mauery66501642018-07-30 09:07:10 -070018 }
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 Mauery9e801a22018-10-12 13:20:49 -070046 const std::vector<uint8_t>&, const 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{
117
Vernon Mauery9e801a22018-10-12 13:20:49 -0700118 public:
119 Entry(CommandID command, session::Privilege privilege) :
120 command(command), privilege(privilege)
121 {
122 }
Tom Joseph07181f52016-08-08 08:17:08 -0500123
Vernon Mauery9e801a22018-10-12 13:20:49 -0700124 /**
125 * @brief Execute the command
126 *
127 * Execute the command
128 *
129 * @param[in] commandData - Request Data for the command
130 * @param[in] handler - Reference to the Message Handler
131 *
132 * @return Response data for the command
133 */
134 virtual std::vector<uint8_t>
135 executeCommand(std::vector<uint8_t>& commandData,
136 const message::Handler& handler) = 0;
Tom Joseph07181f52016-08-08 08:17:08 -0500137
Vernon Mauery9e801a22018-10-12 13:20:49 -0700138 auto getCommand() const
139 {
140 return command;
141 }
Tom Joseph07181f52016-08-08 08:17:08 -0500142
Vernon Mauery9e801a22018-10-12 13:20:49 -0700143 auto getPrivilege() const
144 {
145 return privilege;
146 }
Tom Joseph07181f52016-08-08 08:17:08 -0500147
Vernon Mauery9e801a22018-10-12 13:20:49 -0700148 virtual ~Entry() = default;
149 Entry(const Entry&) = default;
150 Entry& operator=(const Entry&) = default;
151 Entry(Entry&&) = default;
152 Entry& operator=(Entry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500153
Vernon Mauery9e801a22018-10-12 13:20:49 -0700154 protected:
155 CommandID command;
Tom Joseph07181f52016-08-08 08:17:08 -0500156
Vernon Mauery9e801a22018-10-12 13:20:49 -0700157 // Specifies the minimum privilege level required to execute this command
158 session::Privilege privilege;
Tom Joseph07181f52016-08-08 08:17:08 -0500159};
160
Tom Joseph3563f8f2017-05-08 15:42:54 +0530161/**
Tom Joseph07181f52016-08-08 08:17:08 -0500162 * @class NetIpmidEntry
163 *
164 * NetIpmidEntry is used to register commands that are consumed only in
165 * phosphor-net-ipmid. The RAKP commands, session commands and user management
166 * commands are examples of this.
167 *
168 * There are certain IPMI commands that can be executed before session can be
169 * established like Get System GUID, Get Channel Authentication Capabilities
170 * and RAKP commands.
171 */
Vernon Mauery9e801a22018-10-12 13:20:49 -0700172class NetIpmidEntry final : public Entry
Tom Joseph07181f52016-08-08 08:17:08 -0500173{
174
Vernon Mauery9e801a22018-10-12 13:20:49 -0700175 public:
176 NetIpmidEntry(CommandID command, CommandFunctor functor,
177 session::Privilege privilege, bool sessionless) :
178 Entry(command, privilege),
179 functor(functor), sessionless(sessionless)
180 {
181 }
Tom Joseph07181f52016-08-08 08:17:08 -0500182
Vernon Mauery9e801a22018-10-12 13:20:49 -0700183 /**
184 * @brief Execute the command
185 *
186 * Execute the command
187 *
188 * @param[in] commandData - Request Data for the command
189 * @param[in] handler - Reference to the Message Handler
190 *
191 * @return Response data for the command
192 */
193 std::vector<uint8_t>
194 executeCommand(std::vector<uint8_t>& commandData,
195 const message::Handler& handler) override;
Tom Joseph07181f52016-08-08 08:17:08 -0500196
Vernon Mauery9e801a22018-10-12 13:20:49 -0700197 virtual ~NetIpmidEntry() = default;
198 NetIpmidEntry(const NetIpmidEntry&) = default;
199 NetIpmidEntry& operator=(const NetIpmidEntry&) = default;
200 NetIpmidEntry(NetIpmidEntry&&) = default;
201 NetIpmidEntry& operator=(NetIpmidEntry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500202
Vernon Mauery9e801a22018-10-12 13:20:49 -0700203 private:
204 CommandFunctor functor;
Tom Joseph07181f52016-08-08 08:17:08 -0500205
Vernon Mauery9e801a22018-10-12 13:20:49 -0700206 bool sessionless;
Tom Joseph07181f52016-08-08 08:17:08 -0500207};
208
Tom Joseph3563f8f2017-05-08 15:42:54 +0530209/**
Tom Joseph07181f52016-08-08 08:17:08 -0500210 * @class Table
211 *
212 * Table keeps the IPMI command entries as a sorted associative container with
213 * Command ID as the unique key. It has interfaces for registering commands
214 * and executing a command.
215 */
216class Table
217{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700218 public:
219 Table() = default;
220 ~Table() = default;
221 // Command Table is a singleton so copy, copy-assignment, move and
222 // move assignment is deleted
223 Table(const Table&) = delete;
224 Table& operator=(const Table&) = delete;
225 Table(Table&&) = default;
226 Table& operator=(Table&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500227
Vernon Mauery9e801a22018-10-12 13:20:49 -0700228 using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;
Tom Joseph07181f52016-08-08 08:17:08 -0500229
Vernon Mauery9e801a22018-10-12 13:20:49 -0700230 /**
231 * @brief Register a command
232 *
233 * Register a command with the command table
234 *
235 * @param[in] inCommand - Command ID
236 * @param[in] entry - Command Entry
237 *
238 * @return: None
239 *
240 * @note: Duplicate registrations will be rejected.
241 *
242 */
243 void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry);
Tom Joseph07181f52016-08-08 08:17:08 -0500244
Vernon Mauery9e801a22018-10-12 13:20:49 -0700245 /**
246 * @brief Execute the command
247 *
248 * Execute the command for the corresponding CommandID
249 *
250 * @param[in] inCommand - Command ID to execute.
251 * @param[in] commandData - Request Data for the command
252 * @param[in] handler - Reference to the Message Handler
253 *
254 * @return Response data for the command
255 */
256 std::vector<uint8_t> executeCommand(uint32_t inCommand,
257 std::vector<uint8_t>& commandData,
258 const message::Handler& handler);
Tom Joseph07181f52016-08-08 08:17:08 -0500259
Vernon Mauery9e801a22018-10-12 13:20:49 -0700260 private:
261 CommandTable commandTable;
Tom Joseph07181f52016-08-08 08:17:08 -0500262};
263
Vernon Mauery9e801a22018-10-12 13:20:49 -0700264} // namespace command