| #pragma once |
| |
| #include <iostream> |
| #include <numeric> |
| #include "message.hpp" |
| #include "message_parsers.hpp" |
| #include "session.hpp" |
| #include "sol/console_buffer.hpp" |
| |
| namespace message |
| { |
| |
| class Handler |
| { |
| public: |
| explicit Handler(std::shared_ptr<udpsocket::Channel> channel, |
| uint32_t sessionID = |
| message::Message::MESSAGE_INVALID_SESSION_ID): |
| sessionID(sessionID), |
| channel(channel) {} |
| |
| Handler() = delete; |
| ~Handler() = default; |
| Handler(const Handler&) = default; |
| Handler& operator=(const Handler&) = default; |
| Handler(Handler&&) = default; |
| Handler& operator=(Handler&&) = default; |
| |
| /* |
| * @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 |
| * |
| * @return IPMI Message on success and nullptr on failure |
| * |
| */ |
| std::unique_ptr<Message> receive(); |
| |
| /* |
| * @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 |
| * |
| * @param[in] inMessage - Incoming Message |
| * |
| * @return Outgoing message on success and nullptr on failure |
| */ |
| std::unique_ptr<Message> executeCommand(Message& inMessage); |
| |
| /** @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(Message& outMessage); |
| |
| /** @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 sol::Buffer& 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; |
| |
| private: |
| /** @brief Socket channel for communicating with the remote client.*/ |
| std::shared_ptr<udpsocket::Channel> channel; |
| |
| parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20; |
| |
| /* |
| * @brief Create the response IPMI message |
| * |
| * The IPMI outgoing message is constructed out of payload and the |
| * corresponding fields are populated.For the payload type IPMI, the |
| * LAN message header and trailer are added. |
| * |
| * @tparam[in] T - Outgoing message payload type |
| * @param[in] output - Payload for outgoing message |
| * @param[in] inMessage - Incoming IPMI message |
| * |
| * @return Outgoing message on success and nullptr on failure |
| */ |
| template<PayloadType T> |
| std::unique_ptr<Message> createResponse(std::vector<uint8_t>& output, |
| Message& inMessage) |
| { |
| auto outMessage = std::make_unique<Message>(); |
| outMessage->payloadType = T; |
| outMessage->payload = output; |
| return outMessage; |
| } |
| |
| /* |
| * @brief Extract the command from the IPMI payload |
| * |
| * @param[in] message - Incoming message |
| * |
| * @return Command ID in the incoming message |
| */ |
| uint32_t getCommand(Message& message); |
| |
| /* |
| * @brief Calculate 8 bit 2's complement checksum |
| * |
| * Initialize checksum to 0. For each byte, checksum = (checksum + byte) |
| * modulo 256. Then checksum = - checksum. When the checksum and the |
| * bytes are added together, modulo 256, the result should be 0. |
| */ |
| uint8_t crc8bit(const uint8_t* ptr, const size_t len) |
| { |
| return (0x100 - std::accumulate(ptr,ptr+len,0)); |
| } |
| |
| }; |
| |
| } //namespace message |