add initial project structure

Change-Id: I6a3fb080ff623b312e42d71754480a7ce00b81a0
diff --git a/include/generic_io.h b/include/generic_io.h
new file mode 100644
index 0000000..cd8d0e9
--- /dev/null
+++ b/include/generic_io.h
@@ -0,0 +1,123 @@
+/*
+ *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "ip_utils.h"
+
+#include <functional>
+#include <vector>
+#include <chrono>
+#include <system_error>
+#include <cstdint>
+
+#if defined(_MSC_VER)
+#include <BaseTsd.h>
+using ssize_t = SSIZE_T;
+#endif
+
+namespace jami {
+
+template<typename T>
+class GenericSocket
+{
+public:
+    using ValueType = T;
+
+    virtual ~GenericSocket() { shutdown(); }
+
+    using RecvCb = std::function<ssize_t(const ValueType* buf, std::size_t len)>;
+
+    /// Close established connection
+    /// \note Terminate outstanding blocking read operations with an empty error code, but a 0 read size.
+    virtual void shutdown() {}
+
+    /// Set Rx callback
+    /// \warning This method is here for backward compatibility
+    /// and because async IO are not implemented yet.
+    virtual void setOnRecv(RecvCb&& cb) = 0;
+
+    virtual bool isReliable() const = 0;
+
+    virtual bool isInitiator() const = 0;
+
+    /// Return maximum application payload size.
+    /// This value is negative if the session is not ready to give a valid answer.
+    /// The value is 0 if such information is irrelevant for the session.
+    /// If stricly positive, the user must use send() with an input buffer size below or equals
+    /// to this value if it want to be sure that the transport sent it in an atomic way.
+    /// Example: in case of non-reliable transport using packet oriented IO,
+    /// this value gives the maximal size used to send one packet.
+    virtual int maxPayload() const = 0;
+
+    /// Wait until data to read available, timeout or io error
+    /// \param ec error code set in case of error (if return value is < 0)
+    /// \return positive number if data ready for read, 0 in case of timeout or error.
+    /// \note error code is not set in case of timeout, but set only in case of io error
+    /// (i.e. socket deconnection).
+    /// \todo make a std::chrono version for the timeout
+    virtual int waitForData(std::chrono::milliseconds timeout, std::error_code& ec) const = 0;
+
+    /// Write a given amount of data.
+    /// \param buf data to write.
+    /// \param len number of bytes to write.
+    /// \param ec error code set in case of error.
+    /// \return number of bytes written, 0 is valid.
+    /// \warning error checking consists in checking if \a !ec is true, not if returned size is 0
+    /// as a write of 0 could be considered a valid operation.
+    virtual std::size_t write(const ValueType* buf, std::size_t len, std::error_code& ec) = 0;
+
+    /// Read a given amount of data.
+    /// \param buf data to read.
+    /// \param len number of bytes to read.
+    /// \param ec error code set in case of error.
+    /// \return number of bytes read, 0 is valid.
+    /// \warning error checking consists in checking if \a !ec is true, not if returned size is 0
+    /// as a read of 0 could be considered a valid operation (i.e. non-blocking IO).
+    virtual std::size_t read(ValueType* buf, std::size_t len, std::error_code& ec) = 0;
+
+    /// write() adaptor for STL containers
+    template<typename U>
+    std::size_t write(const U& obj, std::error_code& ec)
+    {
+        return write(obj.data(), obj.size() * sizeof(typename U::value_type), ec);
+    }
+
+    /// read() adaptor for STL containers
+    template<typename U>
+    std::size_t read(U& storage, std::error_code& ec)
+    {
+        auto res = read(storage.data(), storage.size() * sizeof(typename U::value_type), ec);
+        if (!ec)
+            storage.resize(res);
+        return res;
+    }
+
+    /// Return the local IP address if known.
+    /// \note The address is not valid (addr.isUnspecified() returns true) if it's not known
+    /// or not available.
+    virtual IpAddr localAddr() const { return {}; }
+
+    /// Return the remote IP address if known.
+    /// \note The address is not valid (addr.isUnspecified() returns true) if it's not known
+    /// or not available.
+    virtual IpAddr remoteAddr() const { return {}; }
+
+protected:
+    GenericSocket() = default;
+};
+
+} // namespace jami