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