1 #pragma once 2 3 #include "message.hpp" 4 #include "message_parsers.hpp" 5 #include "session.hpp" 6 #include "sol/console_buffer.hpp" 7 8 #include <memory> 9 10 namespace message 11 { 12 13 class Handler : public std::enable_shared_from_this<Handler> 14 { 15 public: 16 /** 17 * @brief Create a Handler intended for a full transaction 18 * that may or may not use asynchronous responses 19 */ 20 Handler(std::shared_ptr<udpsocket::Channel> channel, 21 std::shared_ptr<boost::asio::io_context> io, 22 uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) : 23 sessionID(sessionID), 24 channel(channel), io(io) 25 { 26 } 27 28 /** 29 * @brief Create a Handler intended for a send only (SOL) 30 */ 31 Handler(std::shared_ptr<udpsocket::Channel> channel, 32 uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) : 33 sessionID(sessionID), 34 channel(channel), io(nullptr) 35 { 36 } 37 38 ~Handler(); 39 Handler() = delete; 40 Handler(const Handler&) = delete; 41 Handler& operator=(const Handler&) = delete; 42 Handler(Handler&&) = delete; 43 Handler& operator=(Handler&&) = delete; 44 45 /** 46 * @brief Process the incoming IPMI message 47 * 48 * The incoming payload is read from the channel. If a message is read, it 49 * is passed onto executeCommand, which may or may not execute the command 50 * asynchrounously. If the command is executed asynchrounously, a shared_ptr 51 * of self via shared_from_this will keep this object alive until the 52 * response is ready. Then on the destructor, the response will be sent. 53 */ 54 void processIncoming(); 55 56 /** @brief Set socket channel in session object */ 57 void setChannelInSession() const; 58 59 /** @brief Send the SOL payload 60 * 61 * The SOL payload is flattened and sent out on the socket 62 * 63 * @param[in] input - SOL Payload 64 */ 65 void sendSOLPayload(const std::vector<uint8_t>& input); 66 67 /** @brief Send the unsolicited IPMI payload to the remote console. 68 * 69 * This is used by commands like SOL activating, in which case the BMC 70 * has to notify the remote console that a SOL payload is activating 71 * on another channel. 72 * 73 * @param[in] netfn - Net function. 74 * @param[in] cmd - Command. 75 * @param[in] input - Command request data. 76 */ 77 void sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd, 78 const std::vector<uint8_t>& input); 79 80 // BMC Session ID for the Channel 81 session::SessionID sessionID; 82 83 /** @brief response to send back */ 84 std::optional<std::vector<uint8_t>> outPayload; 85 86 private: 87 /** 88 * @brief Receive the IPMI packet 89 * 90 * Read the data on the socket, get the parser based on the Session 91 * header type and flatten the payload and generate the IPMI message 92 */ 93 bool receive(); 94 95 /** 96 * @brief Get Session data from the IPMI packet 97 * 98 */ 99 void updSessionData(std::shared_ptr<Message>& inMessage); 100 101 /** 102 * @brief Process the incoming IPMI message 103 * 104 * The incoming message payload is handled and the command handler for 105 * the Network function and Command is executed and the response message 106 * is returned 107 */ 108 void executeCommand(); 109 110 /** @brief Send the outgoing message 111 * 112 * The payload in the outgoing message is flattened and sent out on the 113 * socket 114 * 115 * @param[in] outMessage - Outgoing Message 116 */ 117 void send(std::shared_ptr<Message> outMessage); 118 119 #ifdef RMCP_PING 120 /** @brief Send the outgoing ASF message 121 * 122 * The outgoing ASF message contains only ASF message header 123 * which is flattened and sent out on the socket 124 */ 125 void sendASF(); 126 #endif // RMCP_PING 127 128 /** @brief Write the packet to the socket 129 * 130 * @param[in] packet - Outgoing packet 131 */ 132 void writeData(const std::vector<uint8_t>& packet); 133 134 /** @brief Socket channel for communicating with the remote client.*/ 135 std::shared_ptr<udpsocket::Channel> channel; 136 137 /** @brief asio io context to run asynchrounously */ 138 std::shared_ptr<boost::asio::io_context> io; 139 140 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20; 141 142 std::shared_ptr<message::Message> inMessage; 143 }; 144 145 } // namespace message 146