IPMI Socket Class to encapsulate the socket operations

This class represents the details regarding an IPMI client like IP
address, port number and the file descriptor associated with it. The
operations provided are reading the UDP packet, writing the packet.

Change-Id: I58cde0edb04fd2fbedd3068de83379eebea8508d
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/socket_channel.hpp b/socket_channel.hpp
new file mode 100644
index 0000000..de95bfd
--- /dev/null
+++ b/socket_channel.hpp
@@ -0,0 +1,124 @@
+#pragma once
+
+#include <arpa/inet.h>
+#include <unistd.h>
+
+#include <string>
+#include <tuple>
+#include <vector>
+
+namespace udpsocket
+{
+
+using buffer = std::vector<uint8_t>;
+/** @class Channel
+ *
+ *  @brief Provides encapsulation for UDP socket operations like Read, Peek,
+ *         Write, Remote peer's IP Address and Port.
+ */
+class Channel
+{
+    public:
+        struct SockAddr_t
+        {
+            union
+            {
+                sockaddr sockAddr;
+                sockaddr_in inAddr;
+            };
+            size_t addrSize;
+        };
+
+        /**
+         * @brief Constructor
+         *
+         * Initialize the IPMI socket object with the socket descriptor
+         *
+         * @param [in] File Descriptor for the socket
+         * @param [in] Timeout parameter for the select call
+         *
+         * @return None
+         */
+        Channel(int insockfd, timeval& inTimeout)
+        {
+            sockfd = insockfd;
+            timeout = inTimeout;
+        }
+
+        /**
+         * @brief Fetch the IP address of the remote peer
+         *
+         * Returns the IP address of the remote peer which is connected to this
+         * socket
+         *
+         * @return IP address of the remote peer
+         */
+        std::string getRemoteAddress() const;
+
+        /**
+         * @brief Fetch the port number of the remote peer
+         *
+         * Returns the port number of the remote peer
+         *
+         * @return Port number
+         *
+         */
+        auto getPort() const
+        {
+            return address.inAddr.sin_port;
+        }
+
+        /**
+         * @brief Read the incoming packet
+         *
+         * Reads the data available on the socket
+         *
+         * @return A tuple with return code and vector with the buffer
+         *         In case of success, the vector is populated with the data
+         *         available on the socket and return code is 0.
+         *         In case of error, the return code is < 0 and vector is set
+         *         to size 0.
+         */
+        std::tuple<int, buffer> read();
+
+        /**
+         *  @brief Write the outgoing packet
+         *
+         *  Writes the data in the vector to the socket
+         *
+         *  @param [in] inBuffer
+         *      The vector would be the buffer of data to write to the socket.
+         *
+         *  @return In case of success the return code is 0 and return code is
+         *          < 0 in case of failure.
+         */
+        int write(buffer& inBuffer);
+
+        /**
+         * @brief Returns file descriptor for the socket
+         */
+        auto getHandle(void) const
+        {
+            return sockfd;
+        }
+
+        ~Channel() = default;
+        Channel(const Channel& right) = delete;
+        Channel& operator=(const Channel& right) = delete;
+        Channel(Channel&&) = default;
+        Channel& operator=(Channel&&) = default;
+
+    private:
+        /*
+         * The socket descriptor is the UDP server socket for the IPMI port.
+         * The same socket descriptor is used for multiple ipmi clients and the
+         * life of the descriptor is lifetime of the net-ipmid server. So we
+         * do not need to close the socket descriptor in the cleanup of the
+         * udpsocket class.
+         */
+        int sockfd;
+        SockAddr_t address;
+        timeval timeout;
+};
+
+} // namespace udpsocket