blob: 4b10b9a1f07fd08a282de1f00be5b8ce146bf4c1 [file] [log] [blame]
Tom Josephaaeb29e2016-08-10 06:36:33 -05001#pragma once
2
3#include <arpa/inet.h>
4#include <unistd.h>
5
6#include <string>
7#include <tuple>
8#include <vector>
9
10namespace udpsocket
11{
12
Tom Josephaaeb29e2016-08-10 06:36:33 -050013/** @class Channel
14 *
15 * @brief Provides encapsulation for UDP socket operations like Read, Peek,
16 * Write, Remote peer's IP Address and Port.
17 */
18class Channel
19{
Vernon Mauery9e801a22018-10-12 13:20:49 -070020 public:
21 struct SockAddr_t
22 {
23 union
Tom Josephaaeb29e2016-08-10 06:36:33 -050024 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070025 sockaddr sockAddr;
26 sockaddr_in6 inAddr;
Tom Josephaaeb29e2016-08-10 06:36:33 -050027 };
Vernon Mauery9e801a22018-10-12 13:20:49 -070028 socklen_t addrSize;
29 };
Tom Josephaaeb29e2016-08-10 06:36:33 -050030
Vernon Mauery9e801a22018-10-12 13:20:49 -070031 /**
32 * @brief Constructor
33 *
34 * Initialize the IPMI socket object with the socket descriptor
35 *
36 * @param [in] File Descriptor for the socket
37 * @param [in] Timeout parameter for the select call
38 *
39 * @return None
40 */
Patrick Venturea65e30d2018-10-26 17:55:08 -070041 Channel(int insockfd, timeval& inTimeout) :
42 sockfd(insockfd), timeout(inTimeout)
Vernon Mauery9e801a22018-10-12 13:20:49 -070043 {
Vernon Mauery9e801a22018-10-12 13:20:49 -070044 }
Tom Josephaaeb29e2016-08-10 06:36:33 -050045
Vernon Mauery9e801a22018-10-12 13:20:49 -070046 /**
47 * @brief Fetch the IP address of the remote peer
48 *
49 * Returns the IP address of the remote peer which is connected to this
50 * socket
51 *
52 * @return IP address of the remote peer
53 */
54 std::string getRemoteAddress() const;
Tom Josephaaeb29e2016-08-10 06:36:33 -050055
Vernon Mauery9e801a22018-10-12 13:20:49 -070056 /**
57 * @brief Fetch the port number of the remote peer
58 *
59 * Returns the port number of the remote peer
60 *
61 * @return Port number
62 *
63 */
64 auto getPort() const
65 {
66 return address.inAddr.sin6_port;
67 }
Tom Josephaaeb29e2016-08-10 06:36:33 -050068
Vernon Mauery9e801a22018-10-12 13:20:49 -070069 /**
70 * @brief Read the incoming packet
71 *
72 * Reads the data available on the socket
73 *
74 * @return A tuple with return code and vector with the buffer
75 * In case of success, the vector is populated with the data
76 * available on the socket and return code is 0.
77 * In case of error, the return code is < 0 and vector is set
78 * to size 0.
79 */
80 std::tuple<int, std::vector<uint8_t>> read();
Tom Josephaaeb29e2016-08-10 06:36:33 -050081
Vernon Mauery9e801a22018-10-12 13:20:49 -070082 /**
83 * @brief Write the outgoing packet
84 *
85 * Writes the data in the vector to the socket
86 *
87 * @param [in] inBuffer
88 * The vector would be the buffer of data to write to the socket.
89 *
90 * @return In case of success the return code is 0 and return code is
91 * < 0 in case of failure.
92 */
93 int write(const std::vector<uint8_t>& inBuffer);
Tom Josephaaeb29e2016-08-10 06:36:33 -050094
Vernon Mauery9e801a22018-10-12 13:20:49 -070095 /**
96 * @brief Returns file descriptor for the socket
97 */
98 auto getHandle(void) const
99 {
100 return sockfd;
101 }
Tom Josephaaeb29e2016-08-10 06:36:33 -0500102
Vernon Mauery9e801a22018-10-12 13:20:49 -0700103 ~Channel() = default;
104 Channel(const Channel& right) = delete;
105 Channel& operator=(const Channel& right) = delete;
106 Channel(Channel&&) = default;
107 Channel& operator=(Channel&&) = default;
Tom Josephaaeb29e2016-08-10 06:36:33 -0500108
Vernon Mauery9e801a22018-10-12 13:20:49 -0700109 private:
110 /*
111 * The socket descriptor is the UDP server socket for the IPMI port.
112 * The same socket descriptor is used for multiple ipmi clients and the
113 * life of the descriptor is lifetime of the net-ipmid server. So we
114 * do not need to close the socket descriptor in the cleanup of the
115 * udpsocket class.
116 */
117 int sockfd;
118 SockAddr_t address;
119 timeval timeout;
Tom Josephaaeb29e2016-08-10 06:36:33 -0500120};
121
122} // namespace udpsocket