Squashed 'third_party/rawrtc/rawrtc-common/' content from commit aff7a3a3b

Change-Id: I2cb019410e8d0e1e0bf814577b0ef83aeb32c7fd
git-subtree-dir: third_party/rawrtc/rawrtc-common
git-subtree-split: aff7a3a3b9bbf49f7d2fc8b123edd301825b3e1c
diff --git a/include/meson.build b/include/meson.build
new file mode 100644
index 0000000..6a4e5e9
--- /dev/null
+++ b/include/meson.build
@@ -0,0 +1,3 @@
+# Install headers
+install_headers(files('rawrtcc.h'))
+subdir('rawrtcc')
diff --git a/include/rawrtcc.h b/include/rawrtcc.h
new file mode 100644
index 0000000..fe6c26f
--- /dev/null
+++ b/include/rawrtcc.h
@@ -0,0 +1,6 @@
+#pragma once
+#include "rawrtcc/config.h"
+
+#include "rawrtcc/code.h"
+#include "rawrtcc/message_buffer.h"
+#include "rawrtcc/utils.h"
diff --git a/include/rawrtcc/code.h b/include/rawrtcc/code.h
new file mode 100644
index 0000000..08051e7
--- /dev/null
+++ b/include/rawrtcc/code.h
@@ -0,0 +1,64 @@
+#pragma once
+
+/// Return codes.
+///
+/// To make it easy to test for errors, the *success* return code's
+/// value will always be `0`. Therefore, you can test for errors
+/// in the following way:
+///
+///     enum rawrtc_code const error = rawrtc_some_function();
+///     if (error) {
+///        // Handle the error...
+///     }
+///
+/// **Important**: Add translations for new return codes in
+/// `utils/utils.c`!
+enum rawrtc_code {
+    /// An unknown (or non-translatable) error occurred.
+    RAWRTC_CODE_UNKNOWN_ERROR = -2,
+    /// The necessary functionality has not been implemented.
+    RAWRTC_CODE_NOT_IMPLEMENTED = -1,
+    /// Success! Nothing went wrong - you're fine to proceed.
+    RAWRTC_CODE_SUCCESS = 0,
+    /// Initialisation failed.
+    RAWRTC_CODE_INITIALISE_FAIL,
+    /// Invalid argument.
+    RAWRTC_CODE_INVALID_ARGUMENT,
+    /// Memory could not be allocated.
+    RAWRTC_CODE_NO_MEMORY,
+    /// Invalid state.
+    RAWRTC_CODE_INVALID_STATE,
+    /// Unsupported protocol.
+    RAWRTC_CODE_UNSUPPORTED_PROTOCOL,
+    /// Unsupported algorithm.
+    RAWRTC_CODE_UNSUPPORTED_ALGORITHM,
+    /// No value has been set.
+    /// @note This is often used for functions that change the value of
+    ///       a variable declared outside of the function to indicate
+    ///       that no change occurred.
+    RAWRTC_CODE_NO_VALUE,
+    /// Socket could not be found.
+    RAWRTC_CODE_NO_SOCKET,
+    /// Invalid certificate.
+    RAWRTC_CODE_INVALID_CERTIFICATE,
+    /// Invalid fingerprint.
+    RAWRTC_CODE_INVALID_FINGERPRINT,
+    /// Insufficient space.
+    RAWRTC_CODE_INSUFFICIENT_SPACE,
+    /// Target is still being used.
+    RAWRTC_CODE_STILL_IN_USE,
+    /// Invalid message.
+    RAWRTC_CODE_INVALID_MESSAGE,
+    /// Message is too long.
+    RAWRTC_CODE_MESSAGE_TOO_LONG,
+    /// Try again later.
+    /// @note This is semantically equivalent to `EAGAIN` and
+    ///       `EWOULDBLOCK`.
+    RAWRTC_CODE_TRY_AGAIN_LATER,
+    /// Stopped iterating (early).
+    RAWRTC_CODE_STOP_ITERATION,
+    /// Operation not permitted.
+    RAWRTC_CODE_NOT_PERMITTED,
+    /// An external function returned an error.
+    RAWRTC_CODE_EXTERNAL_ERROR,
+};
diff --git a/include/rawrtcc/config.h.in b/include/rawrtcc/config.h.in
new file mode 100644
index 0000000..852178e
--- /dev/null
+++ b/include/rawrtcc/config.h.in
@@ -0,0 +1,12 @@
+#pragma once
+
+/// Current version of the library.
+///
+/// Follows [Semantic Versioning 2.0.0](https://semver.org)
+#mesondefine RAWRTCC_VERSION
+#mesondefine RAWRTCC_VERSION_MAJOR
+#mesondefine RAWRTCC_VERSION_MINOR
+#mesondefine RAWRTCC_VERSION_PATCH
+
+/// Debug level
+#mesondefine RAWRTC_DEBUG_LEVEL
diff --git a/include/rawrtcc/debug.h b/include/rawrtcc/debug.h
new file mode 100644
index 0000000..c4c75de
--- /dev/null
+++ b/include/rawrtcc/debug.h
@@ -0,0 +1,29 @@
+// Module level overwrites global level if present
+#ifdef RAWRTC_DEBUG_MODULE_LEVEL
+#    define DEBUG_LEVEL 0
+#    if RAWRTC_DEBUG_MODULE_LEVEL == 1
+#        define DEBUG_LEVEL 1
+#    elif RAWRTC_DEBUG_MODULE_LEVEL == 2
+#        define DEBUG_LEVEL 2
+#    elif RAWRTC_DEBUG_MODULE_LEVEL == 3
+#        define DEBUG_LEVEL 3
+#    elif RAWRTC_DEBUG_MODULE_LEVEL == 4
+#        define DEBUG_LEVEL 4
+#    elif RAWRTC_DEBUG_MODULE_LEVEL == 5
+#        define DEBUG_LEVEL 5
+#    elif RAWRTC_DEBUG_MODULE_LEVEL == 6
+#        define DEBUG_LEVEL 6
+#    elif RAWRTC_DEBUG_MODULE_LEVEL == 7
+#        define DEBUG_LEVEL 7
+#    endif
+#else
+#    ifndef RAWRTC_DEBUG_LEVEL
+#        pragma message "RAWRTC_DEBUG_LEVEL is not defined!"
+#    endif
+#    define DEBUG_LEVEL RAWRTC_DEBUG_LEVEL
+#endif
+
+#include <re_dbg.h>
+
+// Undef for next module
+#undef RAWRTC_DEBUG_MODULE_LEVEL
\ No newline at end of file
diff --git a/include/rawrtcc/meson.build b/include/rawrtcc/meson.build
new file mode 100644
index 0000000..c62ee95
--- /dev/null
+++ b/include/rawrtcc/meson.build
@@ -0,0 +1,15 @@
+# Generate configuration header
+configure_file(
+    input: 'config.h.in',
+    output: 'config.h',
+    configuration: configuration,
+    install_dir: '/'.join([get_option('includedir'), 'rawrtcc']))
+
+# Install headers
+includes = files([
+    'code.h',
+    'debug.h',
+    'message_buffer.h',
+    'utils.h',
+])
+install_headers(includes, subdir: 'rawrtcc')
diff --git a/include/rawrtcc/message_buffer.h b/include/rawrtcc/message_buffer.h
new file mode 100644
index 0000000..2385770
--- /dev/null
+++ b/include/rawrtcc/message_buffer.h
@@ -0,0 +1,27 @@
+#pragma once
+#include "code.h"
+#include <re.h>
+
+/// Handler for buffered messages.
+///
+/// Return `true` if the message has been handled successfully and can
+/// be unlinked, `false` to stop processing messages and keep the current
+/// message in the list.
+typedef bool(rawrtc_message_buffer_handler)(
+    struct mbuf* const buffer, void* const context, void* const arg);
+
+/// Create a message buffer and add it to a list.
+enum rawrtc_code rawrtc_message_buffer_append(
+    struct list* const message_buffer,
+    struct mbuf* const buffer,  // referenced
+    void* const context  // referenced, nullable
+);
+
+/// Apply a receive handler to buffered messages.
+///
+/// Will stop iterating and return `RAWRTC_CODE_STOP_ITERATION` in case
+/// the message handler returned `false`.
+enum rawrtc_code rawrtc_message_buffer_clear(
+    struct list* const message_buffer,
+    rawrtc_message_buffer_handler* const message_handler,
+    void* arg);
diff --git a/include/rawrtcc/utils.h b/include/rawrtcc/utils.h
new file mode 100644
index 0000000..8c798eb
--- /dev/null
+++ b/include/rawrtcc/utils.h
@@ -0,0 +1,19 @@
+#pragma once
+#include "code.h"
+
+/// Translate a rawrtc return code to a string.
+char const* rawrtc_code_to_str(enum rawrtc_code const code);
+
+/// Translate an re error to a rawrtc code.
+enum rawrtc_code rawrtc_error_to_code(const int code);
+
+/// Duplicate a string.
+/// `*destinationp` will be set to a copy of `source` and must be
+/// unreferenced.
+enum rawrtc_code rawrtc_strdup(
+    char** const destinationp,  // de-referenced
+    char const* const source);
+
+/// Print a formatted string to a dynamically allocated buffer.
+/// `*destinationp` must be unreferenced.
+enum rawrtc_code rawrtc_sdprintf(char** const destinationp, char* const formatter, ...);