blob: f0d4848e8b6478875efd22333278a575852269d2 [file] [log] [blame]
Tom Josephe6361a22016-08-10 06:56:25 -05001#pragma once
2
Tom Josephe6361a22016-08-10 06:56:25 -05003#include "message.hpp"
4#include "message_parsers.hpp"
5#include "session.hpp"
Lei YU0a4dde42022-07-12 19:42:15 +08006#include "sessions_manager.hpp"
Tom Josephf846fb32017-03-31 10:36:23 +05307#include "sol/console_buffer.hpp"
Tom Josephe6361a22016-08-10 06:56:25 -05008
Vernon Maueryd999ffc2018-10-25 09:16:05 -07009#include <memory>
Vernon Mauery9e801a22018-10-12 13:20:49 -070010
Tom Josephe6361a22016-08-10 06:56:25 -050011namespace message
12{
13
Vernon Mauery8d6f2002018-11-07 09:55:53 -080014class Handler : public std::enable_shared_from_this<Handler>
Tom Josephe6361a22016-08-10 06:56:25 -050015{
Vernon Mauery9e801a22018-10-12 13:20:49 -070016 public:
Vernon Mauery8d6f2002018-11-07 09:55:53 -080017 /**
18 * @brief Create a Handler intended for a full transaction
19 * that may or may not use asynchronous responses
20 */
21 Handler(std::shared_ptr<udpsocket::Channel> channel,
22 std::shared_ptr<boost::asio::io_context> io,
23 uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) :
Vernon Mauery9e801a22018-10-12 13:20:49 -070024 sessionID(sessionID),
Vernon Mauery8d6f2002018-11-07 09:55:53 -080025 channel(channel), io(io)
Lei YU0a4dde42022-07-12 19:42:15 +080026 {
27 if (sessionID != message::Message::MESSAGE_INVALID_SESSION_ID)
28 {
29 session = session::Manager::get().getSession(sessionID);
30 }
31 }
Tom Josephe6361a22016-08-10 06:56:25 -050032
Vernon Mauery8d6f2002018-11-07 09:55:53 -080033 /**
34 * @brief Create a Handler intended for a send only (SOL)
35 */
36 Handler(std::shared_ptr<udpsocket::Channel> channel,
37 uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) :
38 sessionID(sessionID),
39 channel(channel), io(nullptr)
Lei YU0a4dde42022-07-12 19:42:15 +080040 {
41 if (sessionID != message::Message::MESSAGE_INVALID_SESSION_ID)
42 {
43 session = session::Manager::get().getSession(sessionID);
44 }
45 }
Vernon Mauery8d6f2002018-11-07 09:55:53 -080046
47 ~Handler();
Vernon Mauery9e801a22018-10-12 13:20:49 -070048 Handler() = delete;
Vernon Mauery7f268e42018-10-26 10:26:01 -070049 Handler(const Handler&) = delete;
50 Handler& operator=(const Handler&) = delete;
51 Handler(Handler&&) = delete;
52 Handler& operator=(Handler&&) = delete;
Tom Josephe6361a22016-08-10 06:56:25 -050053
Vernon Mauery9e801a22018-10-12 13:20:49 -070054 /**
Vernon Mauery9e801a22018-10-12 13:20:49 -070055 * @brief Process the incoming IPMI message
56 *
Vernon Mauery8d6f2002018-11-07 09:55:53 -080057 * The incoming payload is read from the channel. If a message is read, it
58 * is passed onto executeCommand, which may or may not execute the command
59 * asynchrounously. If the command is executed asynchrounously, a shared_ptr
60 * of self via shared_from_this will keep this object alive until the
61 * response is ready. Then on the destructor, the response will be sent.
Vernon Mauery9e801a22018-10-12 13:20:49 -070062 */
Vernon Mauery8d6f2002018-11-07 09:55:53 -080063 void processIncoming();
Tom Josephe6361a22016-08-10 06:56:25 -050064
Vernon Mauery9e801a22018-10-12 13:20:49 -070065 /** @brief Set socket channel in session object */
66 void setChannelInSession() const;
Tom Josephff848492017-03-31 10:43:48 +053067
Vernon Mauery9e801a22018-10-12 13:20:49 -070068 /** @brief Send the SOL payload
69 *
70 * The SOL payload is flattened and sent out on the socket
71 *
72 * @param[in] input - SOL Payload
73 */
74 void sendSOLPayload(const std::vector<uint8_t>& input);
Tom Joseph22596f22017-03-31 10:52:27 +053075
Vernon Mauery9e801a22018-10-12 13:20:49 -070076 /** @brief Send the unsolicited IPMI payload to the remote console.
77 *
78 * This is used by commands like SOL activating, in which case the BMC
79 * has to notify the remote console that a SOL payload is activating
80 * on another channel.
81 *
82 * @param[in] netfn - Net function.
83 * @param[in] cmd - Command.
84 * @param[in] input - Command request data.
85 */
86 void sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd,
87 const std::vector<uint8_t>& input);
Tom Joseph63d3e492017-03-31 11:01:08 +053088
Vernon Mauery9e801a22018-10-12 13:20:49 -070089 // BMC Session ID for the Channel
90 session::SessionID sessionID;
Tom Josephf846fb32017-03-31 10:36:23 +053091
Vernon Mauery8d6f2002018-11-07 09:55:53 -080092 /** @brief response to send back */
93 std::optional<std::vector<uint8_t>> outPayload;
94
Vernon Mauery9e801a22018-10-12 13:20:49 -070095 private:
Vernon Mauery8d6f2002018-11-07 09:55:53 -080096 /**
97 * @brief Receive the IPMI packet
98 *
99 * Read the data on the socket, get the parser based on the Session
100 * header type and flatten the payload and generate the IPMI message
101 */
102 bool receive();
103
104 /**
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300105 * @brief Get Session data from the IPMI packet
106 *
107 */
108 void updSessionData(std::shared_ptr<Message>& inMessage);
109
110 /**
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800111 * @brief Process the incoming IPMI message
112 *
113 * The incoming message payload is handled and the command handler for
114 * the Network function and Command is executed and the response message
115 * is returned
116 */
117 void executeCommand();
118
119 /** @brief Send the outgoing message
120 *
121 * The payload in the outgoing message is flattened and sent out on the
122 * socket
123 *
124 * @param[in] outMessage - Outgoing Message
125 */
126 void send(std::shared_ptr<Message> outMessage);
127
Kirill Pakhomovde7dd5c2021-02-27 18:45:22 +0300128#ifdef RMCP_PING
129 /** @brief Send the outgoing ASF message
130 *
131 * The outgoing ASF message contains only ASF message header
132 * which is flattened and sent out on the socket
133 */
134 void sendASF();
135#endif // RMCP_PING
136
137 /** @brief Write the packet to the socket
138 *
139 * @param[in] packet - Outgoing packet
140 */
141 void writeData(const std::vector<uint8_t>& packet);
142
Vernon Mauery9e801a22018-10-12 13:20:49 -0700143 /** @brief Socket channel for communicating with the remote client.*/
144 std::shared_ptr<udpsocket::Channel> channel;
Tom Josephe6361a22016-08-10 06:56:25 -0500145
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800146 /** @brief asio io context to run asynchrounously */
147 std::shared_ptr<boost::asio::io_context> io;
148
Vernon Mauery9e801a22018-10-12 13:20:49 -0700149 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20;
Vernon Mauery8d6f2002018-11-07 09:55:53 -0800150
Vernon Maueryec5ddaf2022-08-03 11:00:50 -0700151 std::shared_ptr<message::Message> inMessage{};
Lei YU0a4dde42022-07-12 19:42:15 +0800152
153 /** @brief The IPMI session of the handler */
Vernon Maueryec5ddaf2022-08-03 11:00:50 -0700154 std::shared_ptr<session::Session> session{};
Tom Josephe6361a22016-08-10 06:56:25 -0500155};
156
Vernon Mauery9e801a22018-10-12 13:20:49 -0700157} // namespace message