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 #include <numeric> 10 11 namespace message 12 { 13 14 class Handler 15 { 16 public: 17 explicit Handler( 18 std::shared_ptr<udpsocket::Channel> channel, 19 uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) : 20 sessionID(sessionID), 21 channel(channel) 22 { 23 } 24 25 Handler() = delete; 26 ~Handler() = default; 27 Handler(const Handler&) = default; 28 Handler& operator=(const Handler&) = default; 29 Handler(Handler&&) = default; 30 Handler& operator=(Handler&&) = default; 31 32 /** 33 * @brief Receive the IPMI packet 34 * 35 * Read the data on the socket, get the parser based on the Session 36 * header type and flatten the payload and generate the IPMI message 37 * 38 * @return IPMI Message on success and nullptr on failure 39 * 40 */ 41 std::shared_ptr<Message> receive(); 42 43 /** 44 * @brief Process the incoming IPMI message 45 * 46 * The incoming message payload is handled and the command handler for 47 * the Network function and Command is executed and the response message 48 * is returned 49 * 50 * @param[in] inMessage - Incoming Message 51 * 52 * @return Outgoing message on success and nullptr on failure 53 */ 54 std::shared_ptr<Message> executeCommand(std::shared_ptr<Message> inMessage); 55 56 /** @brief Send the outgoing message 57 * 58 * The payload in the outgoing message is flattened and sent out on the 59 * socket 60 * 61 * @param[in] outMessage - Outgoing Message 62 */ 63 void send(std::shared_ptr<Message> outMessage); 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 private: 93 /** @brief Socket channel for communicating with the remote client.*/ 94 std::shared_ptr<udpsocket::Channel> channel; 95 96 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20; 97 98 /** 99 * @brief Create the response IPMI message 100 * 101 * The IPMI outgoing message is constructed out of payload and the 102 * corresponding fields are populated.For the payload type IPMI, the 103 * LAN message header and trailer are added. 104 * 105 * @tparam[in] T - Outgoing message payload type 106 * @param[in] output - Payload for outgoing message 107 * @param[in] inMessage - Incoming IPMI message 108 * 109 * @return Outgoing message on success and nullptr on failure 110 */ 111 template <PayloadType T> 112 std::shared_ptr<Message> createResponse(std::vector<uint8_t>& output, 113 std::shared_ptr<Message> inMessage) 114 { 115 auto outMessage = std::make_shared<Message>(); 116 outMessage->payloadType = T; 117 outMessage->payload = output; 118 return outMessage; 119 } 120 121 /** 122 * @brief Extract the command from the IPMI payload 123 * 124 * @param[in] message - Incoming message 125 * 126 * @return Command ID in the incoming message 127 */ 128 uint32_t getCommand(std::shared_ptr<Message> message); 129 130 /** 131 * @brief Calculate 8 bit 2's complement checksum 132 * 133 * Initialize checksum to 0. For each byte, checksum = (checksum + byte) 134 * modulo 256. Then checksum = - checksum. When the checksum and the 135 * bytes are added together, modulo 256, the result should be 0. 136 */ 137 uint8_t crc8bit(const uint8_t* ptr, const size_t len) 138 { 139 return (0x100 - std::accumulate(ptr, ptr + len, 0)); 140 } 141 }; 142 143 } // namespace message 144