1 #pragma once 2 3 #include "message.hpp" 4 #include "message_parsers.hpp" 5 #include "session.hpp" 6 #include "sessions_manager.hpp" 7 #include "sol/console_buffer.hpp" 8 9 #include <memory> 10 11 namespace message 12 { 13 14 class Handler : public std::enable_shared_from_this<Handler> 15 { 16 public: 17 /** 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) : 24 sessionID(sessionID), 25 channel(channel), io(io) 26 { 27 if (sessionID != message::Message::MESSAGE_INVALID_SESSION_ID) 28 { 29 session = session::Manager::get().getSession(sessionID); 30 } 31 } 32 33 /** 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) 40 { 41 if (sessionID != message::Message::MESSAGE_INVALID_SESSION_ID) 42 { 43 session = session::Manager::get().getSession(sessionID); 44 } 45 } 46 47 ~Handler(); 48 Handler() = delete; 49 Handler(const Handler&) = delete; 50 Handler& operator=(const Handler&) = delete; 51 Handler(Handler&&) = delete; 52 Handler& operator=(Handler&&) = delete; 53 54 /** 55 * @brief Process the incoming IPMI message 56 * 57 * 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. 62 */ 63 void processIncoming(); 64 65 /** @brief Set socket channel in session object */ 66 void setChannelInSession() const; 67 68 /** @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); 75 76 /** @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); 88 89 // BMC Session ID for the Channel 90 session::SessionID sessionID; 91 92 /** @brief response to send back */ 93 std::optional<std::vector<uint8_t>> outPayload; 94 95 private: 96 /** 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 /** 105 * @brief Get Session data from the IPMI packet 106 * 107 */ 108 void updSessionData(std::shared_ptr<Message>& inMessage); 109 110 /** 111 * @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 128 #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 143 /** @brief Socket channel for communicating with the remote client.*/ 144 std::shared_ptr<udpsocket::Channel> channel; 145 146 /** @brief asio io context to run asynchrounously */ 147 std::shared_ptr<boost::asio::io_context> io; 148 149 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20; 150 151 std::shared_ptr<message::Message> inMessage; 152 153 /** @brief The IPMI session of the handler */ 154 std::shared_ptr<session::Session> session; 155 }; 156 157 } // namespace message 158