blob: 821a07015ff7218e43df882b2bc47ce586be309f [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;
Patrick Williams099fb092023-05-10 07:50:31 -050017 CommandID(uint32_t command) : command(command) {}
Tom Joseph07181f52016-08-08 08:17:08 -050018
Vernon Mauery66501642018-07-30 09:07:10 -070019 uint8_t netFnLun() const
20 {
21 return static_cast<uint8_t>(command >> CHAR_BIT);
22 }
23 uint8_t netFn() const
24 {
25 return netFnLun() >> lunBits;
26 }
27 uint8_t lun() const
28 {
29 return netFnLun() & ((1 << (lunBits + 1)) - 1);
30 }
31 uint8_t cmd() const
32 {
33 return static_cast<uint8_t>(command);
34 }
35 uint32_t command;
36};
Tom Joseph07181f52016-08-08 08:17:08 -050037
Tom Joseph3563f8f2017-05-08 15:42:54 +053038/**
Tom Joseph07181f52016-08-08 08:17:08 -050039 * CommandFunctor is the functor register for commands defined in
40 * phosphor-net-ipmid. This would take the request part of the command as a
41 * vector and a reference to the message handler. The response part of the
42 * command is returned as a vector.
43 */
44using CommandFunctor = std::function<std::vector<uint8_t>(
Vernon Mauery41ff9b52021-06-11 11:37:40 -070045 const std::vector<uint8_t>&, std::shared_ptr<message::Handler>&)>;
Tom Joseph07181f52016-08-08 08:17:08 -050046
Tom Joseph3563f8f2017-05-08 15:42:54 +053047/**
Tom Joseph07181f52016-08-08 08:17:08 -050048 * @struct CmdDetails
49 *
50 * Command details is used to register commands supported in phosphor-net-ipmid.
51 */
52struct CmdDetails
53{
54 CommandID command;
55 CommandFunctor functor;
56 session::Privilege privilege;
57 bool sessionless;
58};
59
Tom Joseph3563f8f2017-05-08 15:42:54 +053060/**
Tom Joseph07181f52016-08-08 08:17:08 -050061 * @enum NetFns
62 *
63 * A field that identifies the functional class of the message. The Network
64 * Function clusters IPMI commands into different sets.
65 */
66enum class NetFns
67{
Vernon Mauery9e801a22018-10-12 13:20:49 -070068 CHASSIS = (0x00 << 10),
69 CHASSIS_RESP = (0x01 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050070
Vernon Mauery9e801a22018-10-12 13:20:49 -070071 BRIDGE = (0x02 << 10),
72 BRIDGE_RESP = (0x03 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050073
Vernon Mauery9e801a22018-10-12 13:20:49 -070074 SENSOR = (0x04 << 10),
75 SENSOR_RESP = (0x05 << 10),
76 EVENT = (0x04 << 10),
77 EVENT_RESP = (0x05 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050078
Vernon Mauery9e801a22018-10-12 13:20:49 -070079 APP = (0x06 << 10),
80 APP_RESP = (0x07 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050081
Vernon Mauery9e801a22018-10-12 13:20:49 -070082 FIRMWARE = (0x08 << 10),
83 FIRMWARE_RESP = (0x09 << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050084
Vernon Mauery9e801a22018-10-12 13:20:49 -070085 STORAGE = (0x0A << 10),
86 STORAGE_RESP = (0x0B << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050087
Vernon Mauery9e801a22018-10-12 13:20:49 -070088 TRANSPORT = (0x0C << 10),
89 TRANSPORT_RESP = (0x0D << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050090
91 //>>
Vernon Mauery9e801a22018-10-12 13:20:49 -070092 RESERVED_START = (0x0E << 10),
93 RESERVED_END = (0x2B << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050094 //<<
95
Vernon Mauery9e801a22018-10-12 13:20:49 -070096 GROUP_EXTN = (0x2C << 10),
97 GROUP_EXTN_RESP = (0x2D << 10),
Tom Joseph07181f52016-08-08 08:17:08 -050098
Vernon Mauery9e801a22018-10-12 13:20:49 -070099 OEM = (0x2E << 10),
100 OEM_RESP = (0x2F << 10),
Tom Joseph07181f52016-08-08 08:17:08 -0500101};
102
Tom Joseph3563f8f2017-05-08 15:42:54 +0530103/**
Tom Joseph07181f52016-08-08 08:17:08 -0500104 * @class Entry
105 *
106 * This is the base class for registering IPMI commands. There are two ways of
107 * registering commands to phosphor-net-ipmid, the session related commands and
108 * provider commands
109 *
110 * Every commands has a privilege level which mentions the minimum session
111 * privilege level needed to execute the command
112 */
113
114class Entry
115{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700116 public:
117 Entry(CommandID command, session::Privilege privilege) :
118 command(command), privilege(privilege)
George Liubc8958f2022-07-04 09:29:49 +0800119 {}
Tom Joseph07181f52016-08-08 08:17:08 -0500120
Vernon Mauery9e801a22018-10-12 13:20:49 -0700121 /**
122 * @brief Execute the command
123 *
124 * Execute the command
125 *
126 * @param[in] commandData - Request Data for the command
127 * @param[in] handler - Reference to the Message Handler
128 *
129 * @return Response data for the command
130 */
131 virtual std::vector<uint8_t>
132 executeCommand(std::vector<uint8_t>& commandData,
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800133 std::shared_ptr<message::Handler> handler) = 0;
Tom Joseph07181f52016-08-08 08:17:08 -0500134
Vernon Mauery9e801a22018-10-12 13:20:49 -0700135 auto getCommand() const
136 {
137 return command;
138 }
Tom Joseph07181f52016-08-08 08:17:08 -0500139
Vernon Mauery9e801a22018-10-12 13:20:49 -0700140 auto getPrivilege() const
141 {
142 return privilege;
143 }
Tom Joseph07181f52016-08-08 08:17:08 -0500144
Vernon Mauery9e801a22018-10-12 13:20:49 -0700145 virtual ~Entry() = default;
146 Entry(const Entry&) = default;
147 Entry& operator=(const Entry&) = default;
148 Entry(Entry&&) = default;
149 Entry& operator=(Entry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500150
Vernon Mauery9e801a22018-10-12 13:20:49 -0700151 protected:
152 CommandID command;
Tom Joseph07181f52016-08-08 08:17:08 -0500153
Vernon Mauery9e801a22018-10-12 13:20:49 -0700154 // Specifies the minimum privilege level required to execute this command
155 session::Privilege privilege;
Tom Joseph07181f52016-08-08 08:17:08 -0500156};
157
Tom Joseph3563f8f2017-05-08 15:42:54 +0530158/**
Tom Joseph07181f52016-08-08 08:17:08 -0500159 * @class NetIpmidEntry
160 *
161 * NetIpmidEntry is used to register commands that are consumed only in
162 * phosphor-net-ipmid. The RAKP commands, session commands and user management
163 * commands are examples of this.
164 *
165 * There are certain IPMI commands that can be executed before session can be
166 * established like Get System GUID, Get Channel Authentication Capabilities
167 * and RAKP commands.
168 */
Vernon Mauery9e801a22018-10-12 13:20:49 -0700169class NetIpmidEntry final : public Entry
Tom Joseph07181f52016-08-08 08:17:08 -0500170{
Vernon Mauery9e801a22018-10-12 13:20:49 -0700171 public:
172 NetIpmidEntry(CommandID command, CommandFunctor functor,
173 session::Privilege privilege, bool sessionless) :
Patrick Williams84256242024-08-16 15:20:21 -0400174 Entry(command, privilege), functor(functor), sessionless(sessionless)
George Liubc8958f2022-07-04 09:29:49 +0800175 {}
Tom Joseph07181f52016-08-08 08:17:08 -0500176
Vernon Mauery9e801a22018-10-12 13:20:49 -0700177 /**
178 * @brief Execute the command
179 *
180 * Execute the command
181 *
182 * @param[in] commandData - Request Data for the command
183 * @param[in] handler - Reference to the Message Handler
184 *
185 * @return Response data for the command
186 */
187 std::vector<uint8_t>
188 executeCommand(std::vector<uint8_t>& commandData,
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800189 std::shared_ptr<message::Handler> handler) override;
Tom Joseph07181f52016-08-08 08:17:08 -0500190
Vernon Mauery9e801a22018-10-12 13:20:49 -0700191 virtual ~NetIpmidEntry() = default;
192 NetIpmidEntry(const NetIpmidEntry&) = default;
193 NetIpmidEntry& operator=(const NetIpmidEntry&) = default;
194 NetIpmidEntry(NetIpmidEntry&&) = default;
195 NetIpmidEntry& operator=(NetIpmidEntry&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500196
Vernon Mauery9e801a22018-10-12 13:20:49 -0700197 private:
198 CommandFunctor functor;
Tom Joseph07181f52016-08-08 08:17:08 -0500199
Vernon Mauery9e801a22018-10-12 13:20:49 -0700200 bool sessionless;
Tom Joseph07181f52016-08-08 08:17:08 -0500201};
202
Tom Joseph3563f8f2017-05-08 15:42:54 +0530203/**
Tom Joseph07181f52016-08-08 08:17:08 -0500204 * @class Table
205 *
206 * Table keeps the IPMI command entries as a sorted associative container with
207 * Command ID as the unique key. It has interfaces for registering commands
208 * and executing a command.
209 */
210class Table
211{
Vernon Mauery2085ae02021-06-10 11:51:00 -0700212 private:
213 struct Private
George Liubc8958f2022-07-04 09:29:49 +0800214 {};
Vernon Mauery2085ae02021-06-10 11:51:00 -0700215
Vernon Mauery9e801a22018-10-12 13:20:49 -0700216 public:
Patrick Williams099fb092023-05-10 07:50:31 -0500217 explicit Table(const Private&) {}
Vernon Mauery2085ae02021-06-10 11:51:00 -0700218 Table() = delete;
Vernon Mauery9e801a22018-10-12 13:20:49 -0700219 ~Table() = default;
220 // Command Table is a singleton so copy, copy-assignment, move and
221 // move assignment is deleted
222 Table(const Table&) = delete;
223 Table& operator=(const Table&) = delete;
224 Table(Table&&) = default;
225 Table& operator=(Table&&) = default;
Tom Joseph07181f52016-08-08 08:17:08 -0500226
Vernon Mauery2085ae02021-06-10 11:51:00 -0700227 /**
228 * @brief Get a reference to the singleton Table
229 *
230 * @return Table reference
231 */
232 static Table& get()
233 {
234 static std::shared_ptr<Table> ptr = nullptr;
235 if (!ptr)
236 {
237 ptr = std::make_shared<Table>(Private());
238 }
239 return *ptr;
240 }
241
Vernon Mauery9e801a22018-10-12 13:20:49 -0700242 using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;
Tom Joseph07181f52016-08-08 08:17:08 -0500243
Vernon Mauery9e801a22018-10-12 13:20:49 -0700244 /**
245 * @brief Register a command
246 *
247 * Register a command with the command table
248 *
249 * @param[in] inCommand - Command ID
250 * @param[in] entry - Command Entry
251 *
252 * @return: None
253 *
254 * @note: Duplicate registrations will be rejected.
255 *
256 */
257 void registerCommand(CommandID inCommand, std::unique_ptr<Entry>&& entry);
Tom Joseph07181f52016-08-08 08:17:08 -0500258
Vernon Mauery9e801a22018-10-12 13:20:49 -0700259 /**
260 * @brief Execute the command
261 *
262 * Execute the command for the corresponding CommandID
263 *
264 * @param[in] inCommand - Command ID to execute.
265 * @param[in] commandData - Request Data for the command
266 * @param[in] handler - Reference to the Message Handler
267 *
Vernon Mauery9e801a22018-10-12 13:20:49 -0700268 */
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800269 void executeCommand(uint32_t inCommand, std::vector<uint8_t>& commandData,
270 std::shared_ptr<message::Handler> handler);
Tom Joseph07181f52016-08-08 08:17:08 -0500271
Vernon Mauery9e801a22018-10-12 13:20:49 -0700272 private:
273 CommandTable commandTable;
Tom Joseph07181f52016-08-08 08:17:08 -0500274};
275
Vernon Mauery9e801a22018-10-12 13:20:49 -0700276} // namespace command