blob: 40e8020f8789613ab79b4c602f367aa7632f4474 [file] [log] [blame]
Tom Joseph07181f52016-08-08 08:17:08 -05001#pragma once
2
3#include <functional>
4#include <map>
5
6#include "message_handler.hpp"
7
8namespace command
9{
10
11union CommandID
12{
13 uint32_t command;
14
15 uint8_t reserved;
16 message::PayloadType payloadType;
17
18 union
19 {
20 uint8_t netFn: 6;
21 uint8_t lun: 2;
22
23 uint8_t netFnLun;
24 } NetFnLun;
25
26 uint8_t cmd;
27} __attribute__((packed));
28
29/*
30 * CommandFunctor is the functor register for commands defined in
31 * phosphor-net-ipmid. This would take the request part of the command as a
32 * vector and a reference to the message handler. The response part of the
33 * command is returned as a vector.
34 */
35using CommandFunctor = std::function<std::vector<uint8_t>(
36 std::vector<uint8_t>&, const message::Handler&)>;
37
38/*
39 * @struct CmdDetails
40 *
41 * Command details is used to register commands supported in phosphor-net-ipmid.
42 */
43struct CmdDetails
44{
45 CommandID command;
46 CommandFunctor functor;
47 session::Privilege privilege;
48 bool sessionless;
49};
50
51/*
52 * @enum NetFns
53 *
54 * A field that identifies the functional class of the message. The Network
55 * Function clusters IPMI commands into different sets.
56 */
57enum class NetFns
58{
59 CHASSIS = (0x00 << 10),
60 CHASSIS_RESP = (0x01 << 10),
61
62 BRIDGE = (0x02 << 10),
63 BRIDGE_RESP = (0x03 << 10),
64
65 SENSOR = (0x04 << 10),
66 SENSOR_RESP = (0x05 << 10),
67 EVENT = (0x04 << 10),
68 EVENT_RESP = (0x05 << 10),
69
70 APP = (0x06 << 10),
71 APP_RESP = (0x07 << 10),
72
73 FIRMWARE = (0x08 << 10),
74 FIRMWARE_RESP = (0x09 << 10),
75
76 STORAGE = (0x0A << 10),
77 STORAGE_RESP = (0x0B << 10),
78
79 TRANSPORT = (0x0C << 10),
80 TRANSPORT_RESP = (0x0D << 10),
81
82 //>>
83 RESERVED_START = (0x0E << 10),
84 RESERVED_END = (0x2B << 10),
85 //<<
86
87 GROUP_EXTN = (0x2C << 10),
88 GROUP_EXTN_RESP = (0x2D << 10),
89
90 OEM = (0x2E << 10),
91 OEM_RESP = (0x2F << 10),
92};
93
94/*
95 * @class Entry
96 *
97 * This is the base class for registering IPMI commands. There are two ways of
98 * registering commands to phosphor-net-ipmid, the session related commands and
99 * provider commands
100 *
101 * Every commands has a privilege level which mentions the minimum session
102 * privilege level needed to execute the command
103 */
104
105class Entry
106{
107
108 public:
109 Entry(CommandID command, session::Privilege privilege):
110 command(command),
111 privilege(privilege) {}
112
113 /**
114 * @brief Execute the command
115 *
116 * Execute the command
117 *
118 * @param[in] commandData - Request Data for the command
119 * @param[in] handler - Reference to the Message Handler
120 *
121 * @return Response data for the command
122 */
123 virtual std::vector<uint8_t> executeCommand(
124 std::vector<uint8_t>& commandData,
125 const message::Handler& handler) = 0;
126
127 auto getCommand() const
128 {
129 return command;
130 }
131
132 auto getPrivilege() const
133 {
134 return privilege;
135 }
136
137 virtual ~Entry() = default;
138 Entry(const Entry&) = default;
139 Entry& operator=(const Entry&) = default;
140 Entry(Entry&&) = default;
141 Entry& operator=(Entry&&) = default;
142
143 protected:
144 CommandID command;
145
146 //Specifies the minimum privilege level required to execute this command
147 session::Privilege privilege;
148};
149
150/*
151 * @class NetIpmidEntry
152 *
153 * NetIpmidEntry is used to register commands that are consumed only in
154 * phosphor-net-ipmid. The RAKP commands, session commands and user management
155 * commands are examples of this.
156 *
157 * There are certain IPMI commands that can be executed before session can be
158 * established like Get System GUID, Get Channel Authentication Capabilities
159 * and RAKP commands.
160 */
161class NetIpmidEntry final: public Entry
162{
163
164 public:
165 NetIpmidEntry(CommandID command,
166 CommandFunctor functor,
167 session::Privilege privilege,
168 bool sessionless):
169 Entry(command, privilege),
170 functor(functor),
171 sessionless(sessionless) {}
172
173 /**
174 * @brief Execute the command
175 *
176 * Execute the command
177 *
178 * @param[in] commandData - Request Data for the command
179 * @param[in] handler - Reference to the Message Handler
180 *
181 * @return Response data for the command
182 */
183 std::vector<uint8_t> executeCommand(std::vector<uint8_t>& commandData,
184 const message::Handler& handler)
185 override;
186
187 virtual ~NetIpmidEntry() = default;
188 NetIpmidEntry(const NetIpmidEntry&) = default;
189 NetIpmidEntry& operator=(const NetIpmidEntry&) = default;
190 NetIpmidEntry(NetIpmidEntry&&) = default;
191 NetIpmidEntry& operator=(NetIpmidEntry&&) = default;
192
193 private:
194 CommandFunctor functor;
195
196 bool sessionless;
197};
198
199/*
200 * @class Table
201 *
202 * Table keeps the IPMI command entries as a sorted associative container with
203 * Command ID as the unique key. It has interfaces for registering commands
204 * and executing a command.
205 */
206class Table
207{
208 public:
209
210 Table() = default;
211 ~Table() = default;
212 // Command Table is a singleton so copy, copy-assignment, move and
213 // move assignment is deleted
214 Table(const Table&) = delete;
215 Table& operator=(const Table&) = delete;
216 Table(Table&&) = default;
217 Table& operator=(Table&&) = default;
218
219 using CommandTable = std::map<uint32_t, std::unique_ptr<Entry>>;
220
221 /**
222 * @brief Register a command
223 *
224 * Register a command with the command table
225 *
226 * @param[in] inCommand - Command ID
227 * @param[in] entry - Command Entry
228 *
229 * @return: None
230 *
231 * @note Registering an already registered command will overwrite the
232 * existing entry with the new one.
233 */
234 void registerCommand(CommandID inCommand,
235 std::unique_ptr<Entry>&& entry);
236
237 /**
238 * @brief Execute the command
239 *
240 * Execute the command for the corresponding CommandID
241 *
242 * @param[in] inCommand - Command ID to execute.
243 * @param[in] commandData - Request Data for the command
244 * @param[in] handler - Reference to the Message Handler
245 *
246 * @return Response data for the command
247 */
248 std::vector<uint8_t> executeCommand(uint32_t inCommand,
249 std::vector<uint8_t>& commandData,
250 const message::Handler& handler);
251 private:
252 CommandTable commandTable;
253};
254
255}// namespace command