1 #pragma once
2 
3 #include <ipmid/api.h>
4 
5 #include <array>
6 #include <cstddef>
7 #include <cstdint>
8 #include <functional>
9 #include <ipmid/iana.hpp>
10 #include <vector>
11 
12 namespace oem
13 {
14 constexpr std::size_t groupMagicSize = 3;
15 
16 using Group = std::array<std::uint8_t, groupMagicSize>;
17 
18 // Handler signature includes ipmi cmd to support wildcard cmd match.
19 // Buffers and lengths exclude the OemGroup bytes in the IPMI message.
20 // dataLen supplies length of reqBuf upon call, and should be set to the
21 // length of replyBuf upon return - conventional in this code base.
22 using Handler = std::function<ipmi_ret_t(ipmi_cmd_t,          // cmd byte
23                                          const std::uint8_t*, // reqBuf
24                                          std::uint8_t*,       // replyBuf
25                                          std::size_t*)>;      // dataLen
26 
27 /// Router Interface class.
28 /// @brief Abstract Router Interface
29 class Router
30 {
31   public:
32     virtual ~Router()
33     {
34     }
35 
36     /// Enable message routing to begin.
37     virtual void activate() = 0;
38 
39     /// Register a handler for given OEMNumber & cmd.
40     /// Use IPMI_CMD_WILDCARD to catch any unregistered cmd
41     /// for the given OEMNumber.
42     ///
43     /// @param[in] oen - the OEM Number.
44     /// @param[in] cmd - the Command.
45     /// @param[in] handler - the handler to call given that OEN and
46     ///                      command.
47     virtual void registerHandler(Number oen, ipmi_cmd_t cmd,
48                                  Handler handler) = 0;
49 };
50 
51 /// Expose mutable Router for configuration & activation.
52 ///
53 /// @returns pointer to OEM Router to use.
54 Router* mutableRouter();
55 
56 /// Convert a group to an OEN.
57 ///
58 /// @param[in] oeg - request buffer for IPMI command.
59 /// @return the OEN.
60 constexpr Number toOemNumber(const std::uint8_t oeg[groupMagicSize])
61 {
62     return (oeg[2] << 16) | (oeg[1] << 8) | oeg[0];
63 }
64 
65 /// Given a Group convert to an OEN.
66 ///
67 /// @param[in] oeg - OEM Group reference.
68 /// @return the OEN.
69 constexpr Number toOemNumber(const Group& oeg)
70 {
71     return (oeg[2] << 16) | (oeg[1] << 8) | oeg[0];
72 }
73 
74 /// Given an OEN, conver to the OEM Group.
75 ///
76 /// @param[in] oen - the OEM Number.
77 /// @return the OEM Group.
78 constexpr Group toOemGroup(Number oen)
79 {
80     return Group{static_cast<std::uint8_t>(oen),
81                  static_cast<std::uint8_t>(oen >> 8),
82                  static_cast<std::uint8_t>(oen >> 16)};
83 }
84 
85 } // namespace oem
86