blob: 063f8d2225bfb5c392c5c2bc59cba0111a975433 [file] [log] [blame]
Tom Josephe6361a22016-08-10 06:56:25 -05001#pragma once
2
Tom Josephe6361a22016-08-10 06:56:25 -05003#include "message.hpp"
4#include "message_parsers.hpp"
5#include "session.hpp"
Tom Josephf846fb32017-03-31 10:36:23 +05306#include "sol/console_buffer.hpp"
Tom Josephe6361a22016-08-10 06:56:25 -05007
Vernon Mauery9e801a22018-10-12 13:20:49 -07008#include <iostream>
9#include <numeric>
10
Tom Josephe6361a22016-08-10 06:56:25 -050011namespace message
12{
13
14class Handler
15{
Vernon Mauery9e801a22018-10-12 13:20:49 -070016 public:
17 explicit Handler(
18 std::shared_ptr<udpsocket::Channel> channel,
19 uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) :
20 sessionID(sessionID),
21 channel(channel)
22 {
23 }
Tom Josephe6361a22016-08-10 06:56:25 -050024
Vernon Mauery9e801a22018-10-12 13:20:49 -070025 Handler() = delete;
26 ~Handler() = default;
27 Handler(const Handler&) = default;
28 Handler& operator=(const Handler&) = default;
29 Handler(Handler&&) = default;
30 Handler& operator=(Handler&&) = default;
Tom Josephe6361a22016-08-10 06:56:25 -050031
Vernon Mauery9e801a22018-10-12 13:20:49 -070032 /**
33 * @brief Receive the IPMI packet
34 *
35 * Read the data on the socket, get the parser based on the Session
36 * header type and flatten the payload and generate the IPMI message
37 *
38 * @return IPMI Message on success and nullptr on failure
39 *
40 */
41 std::unique_ptr<Message> receive();
Tom Josephe6361a22016-08-10 06:56:25 -050042
Vernon Mauery9e801a22018-10-12 13:20:49 -070043 /**
44 * @brief Process the incoming IPMI message
45 *
46 * The incoming message payload is handled and the command handler for
47 * the Network function and Command is executed and the response message
48 * is returned
49 *
50 * @param[in] inMessage - Incoming Message
51 *
52 * @return Outgoing message on success and nullptr on failure
53 */
54 std::unique_ptr<Message> executeCommand(Message& inMessage);
Tom Josephe6361a22016-08-10 06:56:25 -050055
Vernon Mauery9e801a22018-10-12 13:20:49 -070056 /** @brief Send the outgoing message
57 *
58 * The payload in the outgoing message is flattened and sent out on the
59 * socket
60 *
61 * @param[in] outMessage - Outgoing Message
62 */
63 void send(Message& outMessage);
Tom Josephe6361a22016-08-10 06:56:25 -050064
Vernon Mauery9e801a22018-10-12 13:20:49 -070065 /** @brief Set socket channel in session object */
66 void setChannelInSession() const;
Tom Josephff848492017-03-31 10:43:48 +053067
Vernon Mauery9e801a22018-10-12 13:20:49 -070068 /** @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 std::vector<uint8_t>& input);
Tom Joseph22596f22017-03-31 10:52:27 +053075
Vernon Mauery9e801a22018-10-12 13:20:49 -070076 /** @brief Send the unsolicited IPMI payload to the remote console.
77 *
78 * This is used by commands like SOL activating, in which case the BMC
79 * has to notify the remote console that a SOL payload is activating
80 * on another channel.
81 *
82 * @param[in] netfn - Net function.
83 * @param[in] cmd - Command.
84 * @param[in] input - Command request data.
85 */
86 void sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd,
87 const std::vector<uint8_t>& input);
Tom Joseph63d3e492017-03-31 11:01:08 +053088
Vernon Mauery9e801a22018-10-12 13:20:49 -070089 // BMC Session ID for the Channel
90 session::SessionID sessionID;
Tom Josephf846fb32017-03-31 10:36:23 +053091
Vernon Mauery9e801a22018-10-12 13:20:49 -070092 private:
93 /** @brief Socket channel for communicating with the remote client.*/
94 std::shared_ptr<udpsocket::Channel> channel;
Tom Josephe6361a22016-08-10 06:56:25 -050095
Vernon Mauery9e801a22018-10-12 13:20:49 -070096 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20;
Tom Josephe6361a22016-08-10 06:56:25 -050097
Vernon Mauery9e801a22018-10-12 13:20:49 -070098 /**
99 * @brief Create the response IPMI message
100 *
101 * The IPMI outgoing message is constructed out of payload and the
102 * corresponding fields are populated.For the payload type IPMI, the
103 * LAN message header and trailer are added.
104 *
105 * @tparam[in] T - Outgoing message payload type
106 * @param[in] output - Payload for outgoing message
107 * @param[in] inMessage - Incoming IPMI message
108 *
109 * @return Outgoing message on success and nullptr on failure
110 */
111 template <PayloadType T>
112 std::unique_ptr<Message> createResponse(std::vector<uint8_t>& output,
113 Message& inMessage)
114 {
115 auto outMessage = std::make_unique<Message>();
116 outMessage->payloadType = T;
117 outMessage->payload = output;
118 return outMessage;
119 }
Tom Josephe6361a22016-08-10 06:56:25 -0500120
Vernon Mauery9e801a22018-10-12 13:20:49 -0700121 /**
122 * @brief Extract the command from the IPMI payload
123 *
124 * @param[in] message - Incoming message
125 *
126 * @return Command ID in the incoming message
127 */
128 uint32_t getCommand(Message& message);
Tom Josephe6361a22016-08-10 06:56:25 -0500129
Vernon Mauery9e801a22018-10-12 13:20:49 -0700130 /**
131 * @brief Calculate 8 bit 2's complement checksum
132 *
133 * Initialize checksum to 0. For each byte, checksum = (checksum + byte)
134 * modulo 256. Then checksum = - checksum. When the checksum and the
135 * bytes are added together, modulo 256, the result should be 0.
136 */
137 uint8_t crc8bit(const uint8_t* ptr, const size_t len)
138 {
139 return (0x100 - std::accumulate(ptr, ptr + len, 0));
140 }
Tom Josephe6361a22016-08-10 06:56:25 -0500141};
142
Vernon Mauery9e801a22018-10-12 13:20:49 -0700143} // namespace message