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