1 #pragma once
2 
3 #include <arpa/inet.h>
4 #include <unistd.h>
5 
6 #include <string>
7 #include <tuple>
8 #include <vector>
9 
10 namespace udpsocket
11 {
12 
13 /** @class Channel
14  *
15  *  @brief Provides encapsulation for UDP socket operations like Read, Peek,
16  *         Write, Remote peer's IP Address and Port.
17  */
18 class Channel
19 {
20   public:
21     struct SockAddr_t
22     {
23         union
24         {
25             sockaddr sockAddr;
26             sockaddr_in6 inAddr;
27         };
28         socklen_t addrSize;
29     };
30 
31     /**
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      */
41     Channel(int insockfd, timeval& inTimeout) :
42         sockfd(insockfd), timeout(inTimeout)
43     {
44     }
45 
46     /**
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;
55 
56     /**
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     }
68 
69     /**
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();
81 
82     /**
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);
94 
95     /**
96      * @brief Returns file descriptor for the socket
97      */
98     auto getHandle(void) const
99     {
100         return sockfd;
101     }
102 
103     ~Channel() = default;
104     Channel(const Channel& right) = delete;
105     Channel& operator=(const Channel& right) = delete;
106     Channel(Channel&&) = default;
107     Channel& operator=(Channel&&) = default;
108 
109   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;
120 };
121 
122 } // namespace udpsocket
123