Merge commit '58e2f5e6d8392a3abc4116d747cac037f53fffa9' as 'third_party/rawrtc/rawrtc-common'
Change-Id: Iabef19d5f5e25843877cee28984323a1664d634e
diff --git a/third_party/rawrtc/rawrtc-common/.circleci/config.yml b/third_party/rawrtc/rawrtc-common/.circleci/config.yml
new file mode 100644
index 0000000..6dc68c8
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/.circleci/config.yml
@@ -0,0 +1,184 @@
+version: 2
+
+shared:
+ host: &shared-host
+ working_directory: ~/rawrtc-common
+ steps:
+ - checkout
+
+ # Configure library
+ - run:
+ name: Configure
+ command: |
+ mkdir build
+ meson build --prefix /tmp/prefix
+
+ # Build library
+ - run:
+ name: Build
+ command: |
+ cd build
+ ninja install
+
+ cross: &shared-cross
+ working_directory: ~/rawrtc-common
+ steps:
+ - checkout
+
+ # Configure library
+ - run:
+ name: Configure
+ command: |
+ mkdir build
+ meson build --prefix /tmp/prefix --cross-file ${CROSS_FILE_NAME}
+
+ # Build library
+ - run:
+ name: Build
+ command: |
+ cd build
+ ninja install
+
+
+jobs:
+ # Host: Ubuntu 14.04 LTS
+ trusty-gcc:
+ <<: *shared-host
+ docker:
+ - image: rawrtc/ci-image:trusty
+ environment:
+ CC: gcc
+ trusty-clang:
+ <<: *shared-host
+ docker:
+ - image: rawrtc/ci-image:trusty
+ environment:
+ CC: clang
+
+ # Host: Ubuntu 16.04 LTS
+ xenial-gcc:
+ <<: *shared-host
+ docker:
+ - image: rawrtc/ci-image:xenial
+ environment:
+ CC: gcc
+ xenial-clang:
+ <<: *shared-host
+ docker:
+ - image: rawrtc/ci-image:xenial
+ environment:
+ CC: clang
+
+ # Host: Ubuntu 18.04 LTS
+ bionic-gcc:
+ <<: *shared-host
+ docker:
+ - image: rawrtc/ci-image:bionic
+ environment:
+ CC: gcc
+ bionic-clang:
+ <<: *shared-host
+ docker:
+ - image: rawrtc/ci-image:bionic
+ environment:
+ CC: clang
+
+ # Host: Arch Linux
+ archlinux-gcc:
+ <<: *shared-host
+ docker:
+ - image: rawrtc/ci-image:archlinux
+ environment:
+ CC: gcc
+ archlinux-clang:
+ <<: *shared-host
+ docker:
+ - image: rawrtc/ci-image:archlinux
+ environment:
+ CC: clang
+
+ # Cross: Linux ARMv6
+ linux-armv6:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:linux-armv6
+
+ # Cross: Linux ARMv7
+ linux-armv7:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:linux-armv7
+
+ # Cross: Android API 16 ARM
+ android-16-arm:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:android-16-arm
+
+ # Cross: Android API 16 x86
+ android-16-x86:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:android-16-x86
+
+ # Cross: Android API 28 ARM
+ android-28-arm:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:android-28-arm
+
+ # Cross: Android API 28 ARM64
+ android-28-arm64:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:android-28-arm64
+
+ # Cross: Android API 28 x86
+ android-28-x86:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:android-28-x86
+
+ # Cross: Android API 28 x86_64
+ android-28-x86_64:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:android-28-x86_64
+
+ # Cross: Windows x86
+ windows-x86:
+ <<: *shared-cross
+ docker:
+ - image: rawrtc/cross-build:windows-x86
+
+ # Cross: Windows x64
+ #windows-x64:
+ # <<: *shared-cross
+ # docker:
+ # - image: rawrtc/cross-build:windows-x64
+
+
+workflows:
+ version: 2
+
+ # Build all
+ build:
+ jobs:
+ - trusty-gcc
+ - trusty-clang
+ - xenial-gcc
+ - xenial-clang
+ - bionic-gcc
+ - bionic-clang
+ - archlinux-gcc
+ - archlinux-clang
+ - linux-armv6
+ - linux-armv7
+ - android-16-arm
+ - android-16-x86
+ - android-28-arm
+ - android-28-arm64
+ - android-28-x86
+ - android-28-x86_64
+ - windows-x86
+ #- windows-x64
diff --git a/third_party/rawrtc/rawrtc-common/.clang-format b/third_party/rawrtc/rawrtc-common/.clang-format
new file mode 100644
index 0000000..97ce43f
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/.clang-format
@@ -0,0 +1,74 @@
+---
+BasedOnStyle: LLVM
+Language: Cpp
+AlignAfterOpenBracket: AlwaysBreak
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: DontAlign
+AlignOperands: true
+AlignTrailingComments: false
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+BinPackArguments: true
+BinPackParameters: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeTernaryOperators: true
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: true
+ColumnLimit: 100
+CommentPragmas: '^ IWYU pragma:'
+ContinuationIndentWidth: 4
+DerivePointerAlignment: false
+DisableFormat: false
+ForEachMacros:
+ - LIST_FOREACH
+IncludeBlocks: Preserve
+IncludeCategories:
+ - Regex: '^"[^\.]+'
+ Priority: 1
+ - Regex: '^"\.\./'
+ Priority: 2
+ - Regex: '^<rawrtcc'
+ Priority: 3
+ - Regex: '^<re\.h'
+ Priority: 4
+ - Regex: '.*'
+ Priority: 5
+IncludeIsMainRegex: '(Test)?$'
+IndentCaseLabels: true
+IndentPPDirectives: AfterHash
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 6000
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: true
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+TabWidth: 4
+UseTab: Never
+...
diff --git a/third_party/rawrtc/rawrtc-common/.gitignore b/third_party/rawrtc/rawrtc-common/.gitignore
new file mode 100644
index 0000000..f332ef2
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/.gitignore
@@ -0,0 +1,47 @@
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+
+# Var
+/var
+
+# Build folders
+/build*
+/docs/_build
+/docs/_xml
+
+# Generated files
+/docs/Doxyfile
+/docs/conf.py
+
+# Subprojects
+/subprojects/re
diff --git a/third_party/rawrtc/rawrtc-common/.travis.yml b/third_party/rawrtc/rawrtc-common/.travis.yml
new file mode 100644
index 0000000..dd200dc
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/.travis.yml
@@ -0,0 +1,29 @@
+# Build matrix
+language: c
+matrix:
+ include:
+ # Mac OS 10.13 (default)
+ - os: osx
+ osx_image: xcode9.4
+ compiler: clang
+
+ # Mac OS 10.13 (latest)
+ - os: osx
+ osx_image: xcode10.1
+ compiler: clang
+
+# Dependencies
+addons:
+ homebrew:
+ packages:
+ - meson
+ - ninja
+ update: true
+
+# Build library
+script:
+ - |
+ mkdir build
+ meson build --prefix /tmp/prefix
+ cd build
+ ninja install
diff --git a/third_party/rawrtc/rawrtc-common/CHANGELOG.md b/third_party/rawrtc/rawrtc-common/CHANGELOG.md
new file mode 100644
index 0000000..56c9808
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/CHANGELOG.md
@@ -0,0 +1,24 @@
+# Changelog
+
+## [0.1.3] (2019-10-15)
+
+* Regression fix for defining the debug level
+
+## [0.1.2] (2019-08-15)
+
+* Fix overriding of the debug level via `RAWRTC_DEBUG_MODULE_LEVEL`
+
+## [0.1.1] (2019-03-10)
+
+* Remove unused struct
+
+## [0.1.0] (2019-03-02)
+
+* Initial release of common functionality required by RAWRTC and RAWRTCDC
+
+
+
+[0.1.3]: https://github.com/rawrtc/rawrtc-common/compare/v0.1.2...v0.1.3
+[0.1.2]: https://github.com/rawrtc/rawrtc-common/compare/v0.1.1...v0.1.2
+[0.1.1]: https://github.com/rawrtc/rawrtc-common/compare/v0.1.0...v0.1.1
+[0.1.0]: https://github.com/rawrtc/rawrtc-common/compare/f2e07ac61bc6947ba1466ea3a7e3e91758bb9ab2...v0.1.0
diff --git a/third_party/rawrtc/rawrtc-common/LICENSE b/third_party/rawrtc/rawrtc-common/LICENSE
new file mode 100644
index 0000000..34a8d75
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/LICENSE
@@ -0,0 +1,25 @@
+BSD 2-Clause License
+
+Copyright (c) 2018, Lennart Grahl
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/rawrtc/rawrtc-common/README.md b/third_party/rawrtc/rawrtc-common/README.md
new file mode 100644
index 0000000..1393680
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/README.md
@@ -0,0 +1,48 @@
+# RAWRTCC
+
+[![CircleCI build status][circleci-badge]][circleci-url]
+[![Travis CI build status][travis-ci-badge]][travis-ci-url]
+[![Join our chat on Gitter][gitter-icon]][gitter]
+
+Contains common functionality required by both [RAWRTC][rawrtc] and
+[RAWRTCDC][rawrtcdc].
+
+## Prerequisites
+
+The following tools are required:
+
+* [git][git]
+* [meson][meson] >= 0.46.0
+* [ninja][ninja] >= 1.5
+* Optional: pkg-config (`pkgconf` for newer FreeBSD versions)
+
+## Build
+
+```bash
+cd <path-to-rawrtcc>
+mkdir build
+meson build
+cd build
+ninja
+```
+
+## Contributing
+
+When creating a pull request, it is recommended to run `format-all.sh` to
+apply a consistent code style.
+
+
+
+[circleci-badge]: https://circleci.com/gh/rawrtc/rawrtc-common.svg?style=shield
+[circleci-url]: https://circleci.com/gh/rawrtc/rawrtc-common
+[travis-ci-badge]: https://travis-ci.org/rawrtc/rawrtc-common.svg?branch=master
+[travis-ci-url]: https://travis-ci.org/rawrtc/rawrtc-common
+[gitter]: https://gitter.im/rawrtc/Lobby
+[gitter-icon]: https://badges.gitter.im/rawrtc/Lobby.svg
+
+[rawrtc]: https://github.com/rawrtc/rawrtc
+[rawrtcdc]: https://github.com/rawrtc/rawrtc-data-channel
+
+[git]: https://git-scm.com
+[meson]: https://mesonbuild.com
+[ninja]: https://ninja-build.org
diff --git a/third_party/rawrtc/rawrtc-common/RELEASING.md b/third_party/rawrtc/rawrtc-common/RELEASING.md
new file mode 100644
index 0000000..30100ec
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/RELEASING.md
@@ -0,0 +1,39 @@
+# Release Process
+
+Signing key: https://lgrahl.de/pub/pgp-key.txt
+
+1. Set variables:
+
+ ```bash
+ export VERSION=<version>
+ export GPG_KEY=3FDB14868A2B36D638F3C495F98FBED10482ABA6
+ ```
+
+2. Update version number in `meson.build` and `CHANGELOG.md`. Also, update the
+ URL with the corresponding tags.
+
+3. Do a signed commit and signed tag of the release:
+
+ ```bash
+ git add meson.build CHANGELOG.md
+ git commit -S${GPG_KEY} -m "Release v${VERSION}"
+ git tag -u ${GPG_KEY} -m "Release v${VERSION}" v${VERSION}
+ ```
+
+4. Push.
+
+ ```bash
+ git push && git push --tags
+ ```
+
+5. Create a new release on GitHub.
+
+6. Prepare CHANGELOG.md for upcoming changes:
+
+ ```md
+ ## [Unreleased] (YYYY-MM-DD)
+
+ * ...
+ ```
+
+7. Pat yourself on the back and celebrate!
diff --git a/third_party/rawrtc/rawrtc-common/format-all.sh b/third_party/rawrtc/rawrtc-common/format-all.sh
new file mode 100755
index 0000000..ba846ae
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/format-all.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+for dir in "include" "src"; do
+ pushd "${dir}" &>/dev/null
+ find . \
+ -type f \
+ \( -name "*.c" -o -name "*.h" \) \
+ -exec clang-format -i '{}' \;
+ popd &>/dev/null
+done
diff --git a/third_party/rawrtc/rawrtc-common/include/meson.build b/third_party/rawrtc/rawrtc-common/include/meson.build
new file mode 100644
index 0000000..6a4e5e9
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/include/meson.build
@@ -0,0 +1,3 @@
+# Install headers
+install_headers(files('rawrtcc.h'))
+subdir('rawrtcc')
diff --git a/third_party/rawrtc/rawrtc-common/include/rawrtcc.h b/third_party/rawrtc/rawrtc-common/include/rawrtcc.h
new file mode 100644
index 0000000..fe6c26f
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/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/third_party/rawrtc/rawrtc-common/include/rawrtcc/code.h b/third_party/rawrtc/rawrtc-common/include/rawrtcc/code.h
new file mode 100644
index 0000000..08051e7
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/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/third_party/rawrtc/rawrtc-common/include/rawrtcc/config.h.in b/third_party/rawrtc/rawrtc-common/include/rawrtcc/config.h.in
new file mode 100644
index 0000000..852178e
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/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/third_party/rawrtc/rawrtc-common/include/rawrtcc/debug.h b/third_party/rawrtc/rawrtc-common/include/rawrtcc/debug.h
new file mode 100644
index 0000000..c4c75de
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/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/third_party/rawrtc/rawrtc-common/include/rawrtcc/meson.build b/third_party/rawrtc/rawrtc-common/include/rawrtcc/meson.build
new file mode 100644
index 0000000..c62ee95
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/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/third_party/rawrtc/rawrtc-common/include/rawrtcc/message_buffer.h b/third_party/rawrtc/rawrtc-common/include/rawrtcc/message_buffer.h
new file mode 100644
index 0000000..2385770
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/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/third_party/rawrtc/rawrtc-common/include/rawrtcc/utils.h b/third_party/rawrtc/rawrtc-common/include/rawrtcc/utils.h
new file mode 100644
index 0000000..8c798eb
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/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, ...);
diff --git a/third_party/rawrtc/rawrtc-common/meson.build b/third_party/rawrtc/rawrtc-common/meson.build
new file mode 100644
index 0000000..421df4b
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/meson.build
@@ -0,0 +1,79 @@
+# Project definition
+project('rawrtcc', 'c',
+ version: '0.1.3',
+ default_options: ['c_std=c99'],
+ meson_version: '>=0.46.0')
+
+# Set compiler warning flags
+compiler = meson.get_compiler('c')
+compiler_args = compiler.get_supported_arguments([
+ '-Wall',
+ '-Wmissing-declarations',
+ '-Wmissing-prototypes',
+ '-Wstrict-prototypes',
+ '-Wbad-function-cast',
+ '-Wsign-compare',
+ '-Wnested-externs',
+ '-Wshadow',
+ '-Waggregate-return',
+ '-Wcast-align',
+ '-Wextra',
+ '-Wold-style-definition',
+ '-Wdeclaration-after-statement',
+ '-Wuninitialized',
+ '-Wshorten-64-to-32',
+ '-pedantic',
+])
+add_project_arguments(compiler_args, language: 'c')
+
+# Configuration
+configuration = configuration_data()
+
+# Dependency: re
+# Note: We need to force using our own fork until re has accepted all our patches
+re_dep = dependency('librawrre',
+ version: '>=0.6.0',
+ fallback: ['re', 're_dep'],
+ required: true)
+
+# Dependencies list
+dependencies = [
+ re_dep,
+]
+
+# Version
+version = meson.project_version()
+version_array = version.split('.')
+configuration.set_quoted('RAWRTCC_VERSION', version)
+configuration.set('RAWRTCC_VERSION_MAJOR', version_array[0])
+configuration.set('RAWRTCC_VERSION_MINOR', version_array[1])
+configuration.set('RAWRTCC_VERSION_PATCH', version_array[2])
+
+# Set debug level
+configuration.set('RAWRTC_DEBUG_LEVEL', get_option('debug_level'))
+
+# Includes
+include_dir = include_directories('include')
+subdir('include')
+
+# Sources
+subdir('src')
+
+# Build library
+rawrtcc = library(meson.project_name(), sources,
+ dependencies: dependencies,
+ include_directories: include_dir,
+ install: true,
+ version: version)
+
+# Declare dependency
+rawrtcc_dep = declare_dependency(
+ include_directories: include_dir,
+ link_with: rawrtcc)
+
+# Generate pkg-config file
+pkg = import('pkgconfig')
+pkg.generate(rawrtcc,
+ name: meson.project_name(),
+ description: 'Common code used in RAWRTC projects.',
+ url: 'https://github.com/rawrtc/rawrtc-common')
diff --git a/third_party/rawrtc/rawrtc-common/meson_options.txt b/third_party/rawrtc/rawrtc-common/meson_options.txt
new file mode 100644
index 0000000..c0c8d72
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/meson_options.txt
@@ -0,0 +1,2 @@
+option('debug_level', type: 'integer', min: 0, max: 7, value: 5,
+ description: 'Global debug level', yield: true)
diff --git a/third_party/rawrtc/rawrtc-common/src/meson.build b/third_party/rawrtc/rawrtc-common/src/meson.build
new file mode 100644
index 0000000..15aec96
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/src/meson.build
@@ -0,0 +1,4 @@
+sources = []
+
+subdir('message_buffer')
+subdir('utils')
diff --git a/third_party/rawrtc/rawrtc-common/src/message_buffer/buffer.c b/third_party/rawrtc/rawrtc-common/src/message_buffer/buffer.c
new file mode 100644
index 0000000..75004f1
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/src/message_buffer/buffer.c
@@ -0,0 +1,99 @@
+#include <rawrtcc/code.h>
+#include <rawrtcc/message_buffer.h>
+#include <re.h>
+
+/*
+ * Message buffer.
+ */
+struct buffered_message {
+ struct le le;
+ struct mbuf* buffer; // referenced
+ void* context; // referenced, nullable
+};
+
+/*
+ * Destructor for an existing buffered message.
+ */
+static void rawrtc_message_buffer_destroy(void* arg) {
+ struct buffered_message* const buffered_message = arg;
+
+ // Un-reference
+ mem_deref(buffered_message->context);
+ mem_deref(buffered_message->buffer);
+}
+
+/*
+ * Create a message buffer and add it to a list.
+ *
+ * TODO: Add timestamp to be able to ignore old messages
+ */
+enum rawrtc_code rawrtc_message_buffer_append(
+ struct list* const message_buffer,
+ struct mbuf* const buffer, // referenced
+ void* const context // referenced, nullable
+) {
+ struct buffered_message* buffered_message;
+
+ // Check arguments
+ if (!message_buffer || !buffer) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Create buffered message
+ buffered_message = mem_zalloc(sizeof(*buffered_message), rawrtc_message_buffer_destroy);
+ if (!buffered_message) {
+ return RAWRTC_CODE_NO_MEMORY;
+ }
+
+ // Set fields
+ buffered_message->buffer = mem_ref(buffer);
+ buffered_message->context = mem_ref(context);
+
+ // Add to list
+ list_append(message_buffer, &buffered_message->le, buffered_message);
+ return RAWRTC_CODE_SUCCESS;
+}
+
+/*
+ * 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) {
+ struct le* le;
+ bool unlink;
+
+ // Check arguments
+ if (!message_buffer || !message_handler) {
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ }
+
+ // Handle each message
+ le = list_head(message_buffer);
+ while (le != NULL) {
+ struct buffered_message* const buffered_message = le->data;
+
+ // Handle message
+ unlink = message_handler(buffered_message->buffer, buffered_message->context, arg);
+ if (unlink) {
+ list_unlink(le);
+ }
+
+ // Get next message
+ le = le->next;
+
+ // Remove message
+ if (unlink) {
+ mem_deref(buffered_message);
+ } else {
+ return RAWRTC_CODE_STOP_ITERATION;
+ }
+ }
+
+ // Done
+ return RAWRTC_CODE_SUCCESS;
+}
diff --git a/third_party/rawrtc/rawrtc-common/src/message_buffer/meson.build b/third_party/rawrtc/rawrtc-common/src/message_buffer/meson.build
new file mode 100644
index 0000000..c95a347
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/src/message_buffer/meson.build
@@ -0,0 +1 @@
+sources += files('buffer.c')
diff --git a/third_party/rawrtc/rawrtc-common/src/utils/meson.build b/third_party/rawrtc/rawrtc-common/src/utils/meson.build
new file mode 100644
index 0000000..d82c551
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/src/utils/meson.build
@@ -0,0 +1 @@
+sources += files('utils.c')
diff --git a/third_party/rawrtc/rawrtc-common/src/utils/utils.c b/third_party/rawrtc/rawrtc-common/src/utils/utils.c
new file mode 100644
index 0000000..d837a60
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/src/utils/utils.c
@@ -0,0 +1,109 @@
+#include <rawrtcc/code.h>
+#include <rawrtcc/utils.h>
+#include <re.h>
+#include <stdarg.h> // va_*
+
+/*
+ * Translate a rawrtc return code to a string.
+ */
+char const* rawrtc_code_to_str(enum rawrtc_code const code) {
+ switch (code) {
+ case RAWRTC_CODE_UNKNOWN_ERROR:
+ return "unknown error";
+ case RAWRTC_CODE_NOT_IMPLEMENTED:
+ return "not implemented";
+ case RAWRTC_CODE_SUCCESS:
+ return "success";
+ case RAWRTC_CODE_INITIALISE_FAIL:
+ return "failed to initialise";
+ case RAWRTC_CODE_INVALID_ARGUMENT:
+ return "invalid argument";
+ case RAWRTC_CODE_NO_MEMORY:
+ return "no memory";
+ case RAWRTC_CODE_INVALID_STATE:
+ return "invalid state";
+ case RAWRTC_CODE_UNSUPPORTED_PROTOCOL:
+ return "unsupported protocol";
+ case RAWRTC_CODE_UNSUPPORTED_ALGORITHM:
+ return "unsupported algorithm";
+ case RAWRTC_CODE_NO_VALUE:
+ return "no value";
+ case RAWRTC_CODE_NO_SOCKET:
+ return "no socket";
+ case RAWRTC_CODE_INVALID_CERTIFICATE:
+ return "invalid certificate";
+ case RAWRTC_CODE_INVALID_FINGERPRINT:
+ return "invalid fingerprint";
+ case RAWRTC_CODE_INSUFFICIENT_SPACE:
+ return "insufficient space";
+ case RAWRTC_CODE_STILL_IN_USE:
+ return "still in use";
+ case RAWRTC_CODE_INVALID_MESSAGE:
+ return "invalid message";
+ case RAWRTC_CODE_MESSAGE_TOO_LONG:
+ return "message too long";
+ case RAWRTC_CODE_TRY_AGAIN_LATER:
+ return "try again later";
+ case RAWRTC_CODE_STOP_ITERATION:
+ return "stop iteration";
+ case RAWRTC_CODE_NOT_PERMITTED:
+ return "not permitted";
+ case RAWRTC_CODE_EXTERNAL_ERROR:
+ return "external callback error-ed";
+ default:
+ return "(no error translation)";
+ }
+}
+
+/*
+ * Translate an re error to a rawrtc code.
+ * TODO: Add codes from trice_lcand_add
+ */
+enum rawrtc_code rawrtc_error_to_code(int const code) {
+ switch (code) {
+ case 0:
+ return RAWRTC_CODE_SUCCESS;
+ case EAGAIN:
+#if (EAGAIN != EWOULDBLOCK)
+ case EWOULDBLOCK:
+#endif
+ return RAWRTC_CODE_TRY_AGAIN_LATER;
+ case EAUTH:
+ return RAWRTC_CODE_INVALID_CERTIFICATE;
+ case EBADMSG:
+ return RAWRTC_CODE_INVALID_MESSAGE;
+ case EINVAL:
+ return RAWRTC_CODE_INVALID_ARGUMENT;
+ case EMSGSIZE:
+ return RAWRTC_CODE_MESSAGE_TOO_LONG;
+ case ENOMEM:
+ return RAWRTC_CODE_NO_MEMORY;
+ case EPERM:
+ return RAWRTC_CODE_NOT_PERMITTED;
+ default:
+ return RAWRTC_CODE_UNKNOWN_ERROR;
+ }
+}
+
+/*
+ * Duplicate a string.
+ * `*destinationp` will be set to a copy of `source` and must be
+ * unreferenced.
+ */
+enum rawrtc_code rawrtc_strdup(char** const destinationp, char const* const source) {
+ int err = str_dup(destinationp, source);
+ return rawrtc_error_to_code(err);
+}
+
+/*
+ * Print a formatted string to a dynamically allocated buffer.
+ * `*destinationp` must be unreferenced.
+ */
+enum rawrtc_code rawrtc_sdprintf(char** const destinationp, char* const formatter, ...) {
+ int err;
+ va_list args;
+ va_start(args, formatter);
+ err = re_vsdprintf(destinationp, formatter, args);
+ va_end(args);
+ return rawrtc_error_to_code(err);
+}
diff --git a/third_party/rawrtc/rawrtc-common/subprojects/re.wrap b/third_party/rawrtc/rawrtc-common/subprojects/re.wrap
new file mode 100644
index 0000000..329ac5a
--- /dev/null
+++ b/third_party/rawrtc/rawrtc-common/subprojects/re.wrap
@@ -0,0 +1,4 @@
+[wrap-git]
+directory = re
+url = https://github.com/rawrtc/re.git
+revision = 9384f3a5f38a03c871270fda566045b3bf57bbee