| #pragma once |
| |
| #include "message.hpp" |
| #include "message_parsers.hpp" |
| #include "session.hpp" |
| #include "sessions_manager.hpp" |
| #include "sol/console_buffer.hpp" |
| |
| #include <memory> |
| |
| namespace message |
| { |
| |
| class Handler : public std::enable_shared_from_this<Handler> |
| { |
| public: |
| /** |
| * @brief Create a Handler intended for a full transaction |
| * that may or may not use asynchronous responses |
| */ |
| Handler(std::shared_ptr<udpsocket::Channel> channel, |
| std::shared_ptr<boost::asio::io_context> io, |
| uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) : |
| sessionID(sessionID), |
| channel(channel), io(io) |
| { |
| if (sessionID != message::Message::MESSAGE_INVALID_SESSION_ID) |
| { |
| session = session::Manager::get().getSession(sessionID); |
| } |
| } |
| |
| /** |
| * @brief Create a Handler intended for a send only (SOL) |
| */ |
| Handler(std::shared_ptr<udpsocket::Channel> channel, |
| uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) : |
| sessionID(sessionID), |
| channel(channel), io(nullptr) |
| { |
| if (sessionID != message::Message::MESSAGE_INVALID_SESSION_ID) |
| { |
| session = session::Manager::get().getSession(sessionID); |
| } |
| } |
| |
| ~Handler(); |
| Handler() = delete; |
| Handler(const Handler&) = delete; |
| Handler& operator=(const Handler&) = delete; |
| Handler(Handler&&) = delete; |
| Handler& operator=(Handler&&) = delete; |
| |
| /** |
| * @brief Process the incoming IPMI message |
| * |
| * The incoming payload is read from the channel. If a message is read, it |
| * is passed onto executeCommand, which may or may not execute the command |
| * asynchrounously. If the command is executed asynchrounously, a shared_ptr |
| * of self via shared_from_this will keep this object alive until the |
| * response is ready. Then on the destructor, the response will be sent. |
| */ |
| void processIncoming(); |
| |
| /** @brief Set socket channel in session object */ |
| void setChannelInSession() const; |
| |
| /** @brief Send the SOL payload |
| * |
| * The SOL payload is flattened and sent out on the socket |
| * |
| * @param[in] input - SOL Payload |
| */ |
| void sendSOLPayload(const std::vector<uint8_t>& input); |
| |
| /** @brief Send the unsolicited IPMI payload to the remote console. |
| * |
| * This is used by commands like SOL activating, in which case the BMC |
| * has to notify the remote console that a SOL payload is activating |
| * on another channel. |
| * |
| * @param[in] netfn - Net function. |
| * @param[in] cmd - Command. |
| * @param[in] input - Command request data. |
| */ |
| void sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd, |
| const std::vector<uint8_t>& input); |
| |
| // BMC Session ID for the Channel |
| session::SessionID sessionID; |
| |
| /** @brief response to send back */ |
| std::optional<std::vector<uint8_t>> outPayload; |
| |
| private: |
| /** |
| * @brief Receive the IPMI packet |
| * |
| * Read the data on the socket, get the parser based on the Session |
| * header type and flatten the payload and generate the IPMI message |
| */ |
| bool receive(); |
| |
| /** |
| * @brief Get Session data from the IPMI packet |
| * |
| */ |
| void updSessionData(std::shared_ptr<Message>& inMessage); |
| |
| /** |
| * @brief Process the incoming IPMI message |
| * |
| * The incoming message payload is handled and the command handler for |
| * the Network function and Command is executed and the response message |
| * is returned |
| */ |
| void executeCommand(); |
| |
| /** @brief Send the outgoing message |
| * |
| * The payload in the outgoing message is flattened and sent out on the |
| * socket |
| * |
| * @param[in] outMessage - Outgoing Message |
| */ |
| void send(std::shared_ptr<Message> outMessage); |
| |
| #ifdef RMCP_PING |
| /** @brief Send the outgoing ASF message |
| * |
| * The outgoing ASF message contains only ASF message header |
| * which is flattened and sent out on the socket |
| */ |
| void sendASF(); |
| #endif // RMCP_PING |
| |
| /** @brief Write the packet to the socket |
| * |
| * @param[in] packet - Outgoing packet |
| */ |
| void writeData(const std::vector<uint8_t>& packet); |
| |
| /** @brief Socket channel for communicating with the remote client.*/ |
| std::shared_ptr<udpsocket::Channel> channel; |
| |
| /** @brief asio io context to run asynchrounously */ |
| std::shared_ptr<boost::asio::io_context> io; |
| |
| parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20; |
| |
| std::shared_ptr<message::Message> inMessage{}; |
| |
| /** @brief The IPMI session of the handler */ |
| std::shared_ptr<session::Session> session{}; |
| }; |
| |
| } // namespace message |