1 #pragma once 2 3 #include <iostream> 4 #include <numeric> 5 #include "message.hpp" 6 #include "message_parsers.hpp" 7 #include "session.hpp" 8 #include "sol/console_buffer.hpp" 9 10 namespace message 11 { 12 13 class Handler 14 { 15 public: 16 explicit Handler(std::shared_ptr<udpsocket::Channel> channel, 17 uint32_t sessionID = 18 message::Message::MESSAGE_INVALID_SESSION_ID): 19 sessionID(sessionID), 20 channel(channel) {} 21 22 Handler() = delete; 23 ~Handler() = default; 24 Handler(const Handler&) = default; 25 Handler& operator=(const Handler&) = default; 26 Handler(Handler&&) = default; 27 Handler& operator=(Handler&&) = default; 28 29 /** 30 * @brief Receive the IPMI packet 31 * 32 * Read the data on the socket, get the parser based on the Session 33 * header type and flatten the payload and generate the IPMI message 34 * 35 * @return IPMI Message on success and nullptr on failure 36 * 37 */ 38 std::unique_ptr<Message> receive(); 39 40 /** 41 * @brief Process the incoming IPMI message 42 * 43 * The incoming message payload is handled and the command handler for 44 * the Network function and Command is executed and the response message 45 * is returned 46 * 47 * @param[in] inMessage - Incoming Message 48 * 49 * @return Outgoing message on success and nullptr on failure 50 */ 51 std::unique_ptr<Message> executeCommand(Message& inMessage); 52 53 /** @brief Send the outgoing message 54 * 55 * The payload in the outgoing message is flattened and sent out on the 56 * socket 57 * 58 * @param[in] outMessage - Outgoing Message 59 */ 60 void send(Message& outMessage); 61 62 /** @brief Set socket channel in session object */ 63 void setChannelInSession() const; 64 65 /** @brief Send the SOL payload 66 * 67 * The SOL payload is flattened and sent out on the socket 68 * 69 * @param[in] input - SOL Payload 70 */ 71 void sendSOLPayload(const std::vector<uint8_t>& input); 72 73 /** @brief Send the unsolicited IPMI payload to the remote console. 74 * 75 * This is used by commands like SOL activating, in which case the BMC 76 * has to notify the remote console that a SOL payload is activating 77 * on another channel. 78 * 79 * @param[in] netfn - Net function. 80 * @param[in] cmd - Command. 81 * @param[in] input - Command request data. 82 */ 83 void sendUnsolicitedIPMIPayload(uint8_t netfn, 84 uint8_t cmd, 85 const std::vector<uint8_t>& input); 86 87 // BMC Session ID for the Channel 88 session::SessionID sessionID; 89 90 private: 91 /** @brief Socket channel for communicating with the remote client.*/ 92 std::shared_ptr<udpsocket::Channel> channel; 93 94 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20; 95 96 /** 97 * @brief Create the response IPMI message 98 * 99 * The IPMI outgoing message is constructed out of payload and the 100 * corresponding fields are populated.For the payload type IPMI, the 101 * LAN message header and trailer are added. 102 * 103 * @tparam[in] T - Outgoing message payload type 104 * @param[in] output - Payload for outgoing message 105 * @param[in] inMessage - Incoming IPMI message 106 * 107 * @return Outgoing message on success and nullptr on failure 108 */ 109 template<PayloadType T> 110 std::unique_ptr<Message> createResponse(std::vector<uint8_t>& output, 111 Message& inMessage) 112 { 113 auto outMessage = std::make_unique<Message>(); 114 outMessage->payloadType = T; 115 outMessage->payload = output; 116 return outMessage; 117 } 118 119 /** 120 * @brief Extract the command from the IPMI payload 121 * 122 * @param[in] message - Incoming message 123 * 124 * @return Command ID in the incoming message 125 */ 126 uint32_t getCommand(Message& message); 127 128 /** 129 * @brief Calculate 8 bit 2's complement checksum 130 * 131 * Initialize checksum to 0. For each byte, checksum = (checksum + byte) 132 * modulo 256. Then checksum = - checksum. When the checksum and the 133 * bytes are added together, modulo 256, the result should be 0. 134 */ 135 uint8_t crc8bit(const uint8_t* ptr, const size_t len) 136 { 137 return (0x100 - std::accumulate(ptr,ptr+len,0)); 138 } 139 140 }; 141 142 } //namespace message 143