blob: 11cc42aae50d67e2703ad2947cb61c12404074be [file] [log] [blame]
Tom Josephe6361a22016-08-10 06:56:25 -05001#pragma once
2
3#include <iostream>
4#include <numeric>
Tom Josephe6361a22016-08-10 06:56:25 -05005#include "message.hpp"
6#include "message_parsers.hpp"
7#include "session.hpp"
Tom Josephf846fb32017-03-31 10:36:23 +05308#include "sol/console_buffer.hpp"
Tom Josephe6361a22016-08-10 06:56:25 -05009
10namespace message
11{
12
13class Handler
14{
15 public:
Tom Josephf846fb32017-03-31 10:36:23 +053016 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) {}
Tom Josephe6361a22016-08-10 06:56:25 -050021
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
Tom Joseph3563f8f2017-05-08 15:42:54 +053029 /**
Tom Josephe6361a22016-08-10 06:56:25 -050030 * @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
Tom Joseph3563f8f2017-05-08 15:42:54 +053040 /**
Tom Josephe6361a22016-08-10 06:56:25 -050041 * @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
Tom Joseph04b30382017-04-03 01:06:51 +053053 /** @brief Send the outgoing message
Tom Josephe6361a22016-08-10 06:56:25 -050054 *
Tom Joseph04b30382017-04-03 01:06:51 +053055 * The payload in the outgoing message is flattened and sent out on the
56 * socket
Tom Josephe6361a22016-08-10 06:56:25 -050057 *
Tom Joseph04b30382017-04-03 01:06:51 +053058 * @param[in] outMessage - Outgoing Message
Tom Josephe6361a22016-08-10 06:56:25 -050059 */
Tom Joseph04b30382017-04-03 01:06:51 +053060 void send(Message& outMessage);
Tom Josephe6361a22016-08-10 06:56:25 -050061
Tom Josephff848492017-03-31 10:43:48 +053062 /** @brief Set socket channel in session object */
63 void setChannelInSession() const;
64
Tom Joseph22596f22017-03-31 10:52:27 +053065 /** @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 sol::Buffer& input);
72
Tom Joseph63d3e492017-03-31 11:01:08 +053073 /** @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
Tom Josephe6361a22016-08-10 06:56:25 -050087 // BMC Session ID for the Channel
88 session::SessionID sessionID;
Tom Josephf846fb32017-03-31 10:36:23 +053089
Tom Josephe6361a22016-08-10 06:56:25 -050090 private:
Tom Josephff848492017-03-31 10:43:48 +053091 /** @brief Socket channel for communicating with the remote client.*/
Tom Josephe6361a22016-08-10 06:56:25 -050092 std::shared_ptr<udpsocket::Channel> channel;
93
Tom Joseph31133bc2017-03-31 10:46:12 +053094 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20;
Tom Josephe6361a22016-08-10 06:56:25 -050095
Tom Joseph3563f8f2017-05-08 15:42:54 +053096 /**
Tom Josephe6361a22016-08-10 06:56:25 -050097 * @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>();
Tom Josephe6361a22016-08-10 06:56:25 -0500114 outMessage->payloadType = T;
115 outMessage->payload = output;
116 return outMessage;
117 }
118
Tom Joseph3563f8f2017-05-08 15:42:54 +0530119 /**
Tom Josephe6361a22016-08-10 06:56:25 -0500120 * @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
Tom Joseph3563f8f2017-05-08 15:42:54 +0530128 /**
Tom Josephe6361a22016-08-10 06:56:25 -0500129 * @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