blob: ee8a04f8ea6d3176e5eeb73274c952abbf2e6518 [file] [log] [blame]
Tom Josephe6361a22016-08-10 06:56:25 -05001#pragma once
2
3#include <iostream>
4#include <numeric>
5
6#include "message.hpp"
7#include "message_parsers.hpp"
8#include "session.hpp"
9
10namespace message
11{
12
13class Handler
14{
15 public:
16
17 explicit Handler(std::shared_ptr<udpsocket::Channel> inChannel):
18 channel(inChannel) {}
19
20 Handler() = delete;
21 ~Handler() = default;
22 Handler(const Handler&) = default;
23 Handler& operator=(const Handler&) = default;
24 Handler(Handler&&) = default;
25 Handler& operator=(Handler&&) = default;
26
27 /*
28 * @brief Receive the IPMI packet
29 *
30 * Read the data on the socket, get the parser based on the Session
31 * header type and flatten the payload and generate the IPMI message
32 *
33 * @return IPMI Message on success and nullptr on failure
34 *
35 */
36 std::unique_ptr<Message> receive();
37
38 /*
39 * @brief Process the incoming IPMI message
40 *
41 * The incoming message payload is handled and the command handler for
42 * the Network function and Command is executed and the response message
43 * is returned
44 *
45 * @param[in] inMessage - Incoming Message
46 *
47 * @return Outgoing message on success and nullptr on failure
48 */
49 std::unique_ptr<Message> executeCommand(Message& inMessage);
50
51 /*
52 * @brief Send the outgoing message
53 *
54 * The payload in the outgoing message is flattened and sent out on the
55 * socket
56 *
57 * @param[in] outMessage - Outgoing Message
58 *
59 * @return Zero on success and <0 on failure
60 */
61 int send(Message& outMessage);
62
63 // BMC Session ID for the Channel
64 session::SessionID sessionID;
65 private:
66 // Socket channel for communicating with the remote client
67 std::shared_ptr<udpsocket::Channel> channel;
68
69 // IPMI 1.5 or IPMI 2.0 Session Header
70 parser::SessionHeader sessionHeader;
71
72 /*
73 * @brief Create the response IPMI message
74 *
75 * The IPMI outgoing message is constructed out of payload and the
76 * corresponding fields are populated.For the payload type IPMI, the
77 * LAN message header and trailer are added.
78 *
79 * @tparam[in] T - Outgoing message payload type
80 * @param[in] output - Payload for outgoing message
81 * @param[in] inMessage - Incoming IPMI message
82 *
83 * @return Outgoing message on success and nullptr on failure
84 */
85 template<PayloadType T>
86 std::unique_ptr<Message> createResponse(std::vector<uint8_t>& output,
87 Message& inMessage)
88 {
89 auto outMessage = std::make_unique<Message>();
90 outMessage->rcSessionID = inMessage.rcSessionID;
91 outMessage->payloadType = T;
92 outMessage->payload = output;
93 return outMessage;
94 }
95
96 /*
97 * @brief Extract the command from the IPMI payload
98 *
99 * @param[in] message - Incoming message
100 *
101 * @return Command ID in the incoming message
102 */
103 uint32_t getCommand(Message& message);
104
105 /*
106 * @brief Calculate 8 bit 2's complement checksum
107 *
108 * Initialize checksum to 0. For each byte, checksum = (checksum + byte)
109 * modulo 256. Then checksum = - checksum. When the checksum and the
110 * bytes are added together, modulo 256, the result should be 0.
111 */
112 uint8_t crc8bit(const uint8_t* ptr, const size_t len)
113 {
114 return (0x100 - std::accumulate(ptr,ptr+len,0));
115 }
116
117};
118
119} //namespace message