blob: 7fd12159279feb3ae097a30605df02775cef92eb [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
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 /*
54 * @brief Send the outgoing message
55 *
56 * The payload in the outgoing message is flattened and sent out on the
57 * socket
58 *
59 * @param[in] outMessage - Outgoing Message
60 *
61 * @return Zero on success and <0 on failure
62 */
63 int send(Message& outMessage);
64
Tom Josephff848492017-03-31 10:43:48 +053065 /** @brief Set socket channel in session object */
66 void setChannelInSession() const;
67
Tom Josephe6361a22016-08-10 06:56:25 -050068 // BMC Session ID for the Channel
69 session::SessionID sessionID;
Tom Josephf846fb32017-03-31 10:36:23 +053070
Tom Josephe6361a22016-08-10 06:56:25 -050071 private:
Tom Josephff848492017-03-31 10:43:48 +053072 /** @brief Socket channel for communicating with the remote client.*/
Tom Josephe6361a22016-08-10 06:56:25 -050073 std::shared_ptr<udpsocket::Channel> channel;
74
75 // IPMI 1.5 or IPMI 2.0 Session Header
76 parser::SessionHeader sessionHeader;
77
78 /*
79 * @brief Create the response IPMI message
80 *
81 * The IPMI outgoing message is constructed out of payload and the
82 * corresponding fields are populated.For the payload type IPMI, the
83 * LAN message header and trailer are added.
84 *
85 * @tparam[in] T - Outgoing message payload type
86 * @param[in] output - Payload for outgoing message
87 * @param[in] inMessage - Incoming IPMI message
88 *
89 * @return Outgoing message on success and nullptr on failure
90 */
91 template<PayloadType T>
92 std::unique_ptr<Message> createResponse(std::vector<uint8_t>& output,
93 Message& inMessage)
94 {
95 auto outMessage = std::make_unique<Message>();
Tom Josephe6361a22016-08-10 06:56:25 -050096 outMessage->payloadType = T;
97 outMessage->payload = output;
98 return outMessage;
99 }
100
101 /*
102 * @brief Extract the command from the IPMI payload
103 *
104 * @param[in] message - Incoming message
105 *
106 * @return Command ID in the incoming message
107 */
108 uint32_t getCommand(Message& message);
109
110 /*
111 * @brief Calculate 8 bit 2's complement checksum
112 *
113 * Initialize checksum to 0. For each byte, checksum = (checksum + byte)
114 * modulo 256. Then checksum = - checksum. When the checksum and the
115 * bytes are added together, modulo 256, the result should be 0.
116 */
117 uint8_t crc8bit(const uint8_t* ptr, const size_t len)
118 {
119 return (0x100 - std::accumulate(ptr,ptr+len,0));
120 }
121
122};
123
124} //namespace message