blob: 3c996603c2656114c7d605ed1e0c96bd0e37bcab [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>
Vernon Maueryd999ffc2018-10-25 09:16:05 -07009#include <memory>
Vernon Mauery9e801a22018-10-12 13:20:49 -070010#include <numeric>
11
Tom Josephe6361a22016-08-10 06:56:25 -050012namespace message
13{
14
15class Handler
16{
Vernon Mauery9e801a22018-10-12 13:20:49 -070017 public:
18 explicit Handler(
19 std::shared_ptr<udpsocket::Channel> channel,
20 uint32_t sessionID = message::Message::MESSAGE_INVALID_SESSION_ID) :
21 sessionID(sessionID),
22 channel(channel)
23 {
24 }
Tom Josephe6361a22016-08-10 06:56:25 -050025
Vernon Mauery9e801a22018-10-12 13:20:49 -070026 Handler() = delete;
27 ~Handler() = default;
28 Handler(const Handler&) = default;
29 Handler& operator=(const Handler&) = default;
30 Handler(Handler&&) = default;
31 Handler& operator=(Handler&&) = default;
Tom Josephe6361a22016-08-10 06:56:25 -050032
Vernon Mauery9e801a22018-10-12 13:20:49 -070033 /**
34 * @brief Receive the IPMI packet
35 *
36 * Read the data on the socket, get the parser based on the Session
37 * header type and flatten the payload and generate the IPMI message
38 *
39 * @return IPMI Message on success and nullptr on failure
40 *
41 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -070042 std::shared_ptr<Message> receive();
Tom Josephe6361a22016-08-10 06:56:25 -050043
Vernon Mauery9e801a22018-10-12 13:20:49 -070044 /**
45 * @brief Process the incoming IPMI message
46 *
47 * The incoming message payload is handled and the command handler for
48 * the Network function and Command is executed and the response message
49 * is returned
50 *
51 * @param[in] inMessage - Incoming Message
52 *
53 * @return Outgoing message on success and nullptr on failure
54 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -070055 std::shared_ptr<Message> executeCommand(std::shared_ptr<Message> inMessage);
Tom Josephe6361a22016-08-10 06:56:25 -050056
Vernon Mauery9e801a22018-10-12 13:20:49 -070057 /** @brief Send the outgoing message
58 *
59 * The payload in the outgoing message is flattened and sent out on the
60 * socket
61 *
62 * @param[in] outMessage - Outgoing Message
63 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -070064 void send(std::shared_ptr<Message> outMessage);
Tom Josephe6361a22016-08-10 06:56:25 -050065
Vernon Mauery9e801a22018-10-12 13:20:49 -070066 /** @brief Set socket channel in session object */
67 void setChannelInSession() const;
Tom Josephff848492017-03-31 10:43:48 +053068
Vernon Mauery9e801a22018-10-12 13:20:49 -070069 /** @brief Send the SOL payload
70 *
71 * The SOL payload is flattened and sent out on the socket
72 *
73 * @param[in] input - SOL Payload
74 */
75 void sendSOLPayload(const std::vector<uint8_t>& input);
Tom Joseph22596f22017-03-31 10:52:27 +053076
Vernon Mauery9e801a22018-10-12 13:20:49 -070077 /** @brief Send the unsolicited IPMI payload to the remote console.
78 *
79 * This is used by commands like SOL activating, in which case the BMC
80 * has to notify the remote console that a SOL payload is activating
81 * on another channel.
82 *
83 * @param[in] netfn - Net function.
84 * @param[in] cmd - Command.
85 * @param[in] input - Command request data.
86 */
87 void sendUnsolicitedIPMIPayload(uint8_t netfn, uint8_t cmd,
88 const std::vector<uint8_t>& input);
Tom Joseph63d3e492017-03-31 11:01:08 +053089
Vernon Mauery9e801a22018-10-12 13:20:49 -070090 // BMC Session ID for the Channel
91 session::SessionID sessionID;
Tom Josephf846fb32017-03-31 10:36:23 +053092
Vernon Mauery9e801a22018-10-12 13:20:49 -070093 private:
94 /** @brief Socket channel for communicating with the remote client.*/
95 std::shared_ptr<udpsocket::Channel> channel;
Tom Josephe6361a22016-08-10 06:56:25 -050096
Vernon Mauery9e801a22018-10-12 13:20:49 -070097 parser::SessionHeader sessionHeader = parser::SessionHeader::IPMI20;
Tom Josephe6361a22016-08-10 06:56:25 -050098
Vernon Mauery9e801a22018-10-12 13:20:49 -070099 /**
100 * @brief Create the response IPMI message
101 *
102 * The IPMI outgoing message is constructed out of payload and the
103 * corresponding fields are populated.For the payload type IPMI, the
104 * LAN message header and trailer are added.
105 *
106 * @tparam[in] T - Outgoing message payload type
107 * @param[in] output - Payload for outgoing message
108 * @param[in] inMessage - Incoming IPMI message
109 *
110 * @return Outgoing message on success and nullptr on failure
111 */
112 template <PayloadType T>
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700113 std::shared_ptr<Message> createResponse(std::vector<uint8_t>& output,
114 std::shared_ptr<Message> inMessage)
Vernon Mauery9e801a22018-10-12 13:20:49 -0700115 {
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700116 auto outMessage = std::make_shared<Message>();
Vernon Mauery9e801a22018-10-12 13:20:49 -0700117 outMessage->payloadType = T;
118 outMessage->payload = output;
119 return outMessage;
120 }
Tom Josephe6361a22016-08-10 06:56:25 -0500121
Vernon Mauery9e801a22018-10-12 13:20:49 -0700122 /**
123 * @brief Extract the command from the IPMI payload
124 *
125 * @param[in] message - Incoming message
126 *
127 * @return Command ID in the incoming message
128 */
Vernon Maueryd999ffc2018-10-25 09:16:05 -0700129 uint32_t getCommand(std::shared_ptr<Message> message);
Tom Josephe6361a22016-08-10 06:56:25 -0500130
Vernon Mauery9e801a22018-10-12 13:20:49 -0700131 /**
132 * @brief Calculate 8 bit 2's complement checksum
133 *
134 * Initialize checksum to 0. For each byte, checksum = (checksum + byte)
135 * modulo 256. Then checksum = - checksum. When the checksum and the
136 * bytes are added together, modulo 256, the result should be 0.
137 */
138 uint8_t crc8bit(const uint8_t* ptr, const size_t len)
139 {
140 return (0x100 - std::accumulate(ptr, ptr + len, 0));
141 }
Tom Josephe6361a22016-08-10 06:56:25 -0500142};
143
Vernon Mauery9e801a22018-10-12 13:20:49 -0700144} // namespace message