blob: 60b7a6d1c7647ab5e9096d4e89adff31ca9b2116 [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 Joseph22596f22017-03-31 10:52:27 +053068 /** @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 sol::Buffer& input);
75
Tom Josephe6361a22016-08-10 06:56:25 -050076 // BMC Session ID for the Channel
77 session::SessionID sessionID;
Tom Josephf846fb32017-03-31 10:36:23 +053078
Tom Josephe6361a22016-08-10 06:56:25 -050079 private:
Tom Josephff848492017-03-31 10:43:48 +053080 /** @brief Socket channel for communicating with the remote client.*/
Tom Josephe6361a22016-08-10 06:56:25 -050081 std::shared_ptr<udpsocket::Channel> channel;
82
Tom Joseph31133bc2017-03-31 10:46:12 +053083 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20;
Tom Josephe6361a22016-08-10 06:56:25 -050084
85 /*
86 * @brief Create the response IPMI message
87 *
88 * The IPMI outgoing message is constructed out of payload and the
89 * corresponding fields are populated.For the payload type IPMI, the
90 * LAN message header and trailer are added.
91 *
92 * @tparam[in] T - Outgoing message payload type
93 * @param[in] output - Payload for outgoing message
94 * @param[in] inMessage - Incoming IPMI message
95 *
96 * @return Outgoing message on success and nullptr on failure
97 */
98 template<PayloadType T>
99 std::unique_ptr<Message> createResponse(std::vector<uint8_t>& output,
100 Message& inMessage)
101 {
102 auto outMessage = std::make_unique<Message>();
Tom Josephe6361a22016-08-10 06:56:25 -0500103 outMessage->payloadType = T;
104 outMessage->payload = output;
105 return outMessage;
106 }
107
108 /*
109 * @brief Extract the command from the IPMI payload
110 *
111 * @param[in] message - Incoming message
112 *
113 * @return Command ID in the incoming message
114 */
115 uint32_t getCommand(Message& message);
116
117 /*
118 * @brief Calculate 8 bit 2's complement checksum
119 *
120 * Initialize checksum to 0. For each byte, checksum = (checksum + byte)
121 * modulo 256. Then checksum = - checksum. When the checksum and the
122 * bytes are added together, modulo 256, the result should be 0.
123 */
124 uint8_t crc8bit(const uint8_t* ptr, const size_t len)
125 {
126 return (0x100 - std::accumulate(ptr,ptr+len,0));
127 }
128
129};
130
131} //namespace message