1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

Upgrade libsrt to v1.5.3. v5.0.183 (#3808)

This commit is contained in:
winlin 2023-09-21 22:31:38 +08:00
parent 389a62ee3a
commit 632d457194
154 changed files with 39813 additions and 17038 deletions

View file

@ -0,0 +1,62 @@
#
# SRT - Secure, Reliable, Transport
# Copyright (c) 2021 Haivision Systems Inc.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Check for c++11 std::atomic.
#
# Sets:
# HAVE_CXX_ATOMIC
# HAVE_CXX_ATOMIC_STATIC
include(CheckCXXSourceCompiles)
include(CheckLibraryExists)
function(CheckCXXAtomic)
unset(HAVE_CXX_ATOMIC CACHE)
unset(HAVE_CXX_ATOMIC_STATIC CACHE)
unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)
set(CheckCXXAtomic_CODE
"
#include<cstdint>
#include<atomic>
int main(void)
{
std::atomic<std::ptrdiff_t> x(0);
std::atomic<std::intmax_t> y(0);
return x + y;
}
")
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
check_cxx_source_compiles(
"${CheckCXXAtomic_CODE}"
HAVE_CXX_ATOMIC)
if(HAVE_CXX_ATOMIC)
# CMAKE_REQUIRED_LINK_OPTIONS was introduced in CMake 3.14.
if(CMAKE_VERSION VERSION_LESS "3.14")
set(CMAKE_REQUIRED_LINK_OPTIONS "-static")
else()
set(CMAKE_REQUIRED_FLAGS "-std=c++11 -static")
endif()
check_cxx_source_compiles(
"${CheckCXXAtomic_CODE}"
HAVE_CXX_ATOMIC_STATIC)
endif()
unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)
endfunction(CheckCXXAtomic)

View file

@ -0,0 +1,57 @@
#
# SRT - Secure, Reliable, Transport Copyright (c) 2022 Haivision Systems Inc.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at http://mozilla.org/MPL/2.0/.
#
# Check for C++11 std::put_time().
#
# Sets:
# HAVE_CXX_STD_PUT_TIME
include(CheckCSourceCompiles)
function(CheckCXXStdPutTime)
unset(HAVE_CXX_STD_PUT_TIME CACHE)
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6
unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)
set(CheckCXXStdPutTime_CODE
"
#include <iostream>
#include <iomanip>
#include <ctime>
int main(void)
{
const int result = 0;
std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t);
std::cout
<< std::put_time(&tm, \"%FT%T\")
<< std::setfill('0')
<< std::setw(6)
<< std::endl;
return result;
}
"
)
# NOTE: Should we set -std or use the current compiler configuration.
# It seems that the top level build does not track the compiler
# in a consistent manner. So Maybe we need this?
set(CMAKE_REQUIRED_FLAGS "-std=c++11")
# Check that the compiler can build the std::put_time() example:
message(STATUS "Checking for C++ 'std::put_time()':")
check_cxx_source_compiles(
"${CheckCXXStdPutTime_CODE}"
HAVE_CXX_STD_PUT_TIME)
endfunction(CheckCXXStdPutTime)

View file

@ -0,0 +1,113 @@
#
# SRT - Secure, Reliable, Transport Copyright (c) 2021 Haivision Systems Inc.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at http://mozilla.org/MPL/2.0/.
#
# Check for GCC Atomic Intrinsics and whether libatomic is required.
#
# Sets:
# HAVE_LIBATOMIC
# HAVE_LIBATOMIC_COMPILES
# HAVE_LIBATOMIC_COMPILES_STATIC
# HAVE_GCCATOMIC_INTRINSICS
# HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC
#
# See
# https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
# https://gcc.gnu.org/wiki/Atomic/GCCMM/AtomicSync
include(CheckCSourceCompiles)
include(CheckLibraryExists)
function(CheckGCCAtomicIntrinsics)
unset(HAVE_LIBATOMIC CACHE)
unset(HAVE_LIBATOMIC_COMPILES CACHE)
unset(HAVE_LIBATOMIC_COMPILES_STATIC CACHE)
unset(HAVE_GCCATOMIC_INTRINSICS CACHE)
unset(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC CACHE)
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6
unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)
# Check for existence of libatomic and whether this symbol is present.
check_library_exists(atomic __atomic_fetch_add_8 "" HAVE_LIBATOMIC)
set(CheckLibAtomicCompiles_CODE
"
int main(void)
{
const int result = 0;
return result;
}
")
set(CMAKE_REQUIRED_LIBRARIES "atomic")
# Check that the compiler can build a simple application and link with
# libatomic.
check_c_source_compiles("${CheckLibAtomicCompiles_CODE}"
HAVE_LIBATOMIC_COMPILES)
if(NOT HAVE_LIBATOMIC_COMPILES)
set(HAVE_LIBATOMIC
0
CACHE INTERNAL "" FORCE)
endif()
if(HAVE_LIBATOMIC AND HAVE_LIBATOMIC_COMPILES)
# CMAKE_REQUIRED_LINK_OPTIONS was introduced in CMake 3.14.
if(CMAKE_VERSION VERSION_LESS "3.14")
set(CMAKE_REQUIRED_LINK_OPTIONS "-static")
else()
set(CMAKE_REQUIRED_FLAGS "-static")
endif()
# Check that the compiler can build a simple application and statically link
# with libatomic.
check_c_source_compiles("${CheckLibAtomicCompiles_CODE}"
HAVE_LIBATOMIC_COMPILES_STATIC)
else()
set(HAVE_LIBATOMIC_COMPILES_STATIC
0
CACHE INTERNAL "" FORCE)
endif()
unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_LIBRARIES)
unset(CMAKE_REQUIRED_LINK_OPTIONS)
set(CheckGCCAtomicIntrinsics_CODE
"
#include<stddef.h>
#include<stdint.h>
int main(void)
{
ptrdiff_t x = 0;
intmax_t y = 0;
__atomic_add_fetch(&x, 1, __ATOMIC_SEQ_CST);
__atomic_add_fetch(&y, 1, __ATOMIC_SEQ_CST);
return __atomic_sub_fetch(&x, 1, __ATOMIC_SEQ_CST)
+ __atomic_sub_fetch(&y, 1, __ATOMIC_SEQ_CST);
}
")
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE) # CMake 3.6
check_c_source_compiles("${CheckGCCAtomicIntrinsics_CODE}"
HAVE_GCCATOMIC_INTRINSICS)
if(NOT HAVE_GCCATOMIC_INTRINSICS AND HAVE_LIBATOMIC)
set(CMAKE_REQUIRED_LIBRARIES "atomic")
check_c_source_compiles("${CheckGCCAtomicIntrinsics_CODE}"
HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC)
if(HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC)
set(HAVE_GCCATOMIC_INTRINSICS
1
CACHE INTERNAL "" FORCE)
endif()
endif()
endfunction(CheckGCCAtomicIntrinsics)

View file

@ -111,5 +111,5 @@ endif()
# Now we've accounted for the 3-vs-1 library case:
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libmbedtls DEFAULT_MSG MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS)
find_package_handle_standard_args(MbedTLS DEFAULT_MSG MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS)
mark_as_advanced(MBEDTLS_INCLUDE_DIR MBEDTLS_LIBRARIES MBEDTLS_INCLUDE_DIRS)

View file

@ -0,0 +1,73 @@
#
# SRT - Secure, Reliable, Transport
# Copyright (c) 2021 Haivision Systems Inc.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Check for pthread_getname_np(3) and pthread_setname_np(3)
# used in srtcore/threadname.h.
#
# Some BSD distros need to include <pthread_np.h> for pthread_getname_np().
#
# TODO: Some BSD distros have pthread_get_name_np() and pthread_set_name_np()
# instead of pthread_getname_np() and pthread_setname_np().
#
# Sets:
# HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H
# HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H
# HAVE_PTHREAD_GETNAME_NP
# HAVE_PTHREAD_SETNAME_NP
# Sets as appropriate:
# add_definitions(-DHAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H=1)
# add_definitions(-DHAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H=1)
# add_definitions(-DHAVE_PTHREAD_GETNAME_NP=1)
# add_definitions(-DHAVE_PTHREAD_SETNAME_NP=1)
include(CheckSymbolExists)
function(FindPThreadGetSetName)
unset(HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H CACHE)
unset(HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H CACHE)
unset(HAVE_PTHREAD_GETNAME_NP CACHE)
unset(HAVE_PTHREAD_SETNAME_NP CACHE)
set(CMAKE_REQUIRED_DEFINITIONS
-D_GNU_SOURCE -D_DARWIN_C_SOURCE -D_POSIX_SOURCE=1)
set(CMAKE_REQUIRED_FLAGS "-pthread")
message(STATUS "Checking for pthread_(g/s)etname_np in 'pthread_np.h':")
check_symbol_exists(
pthread_getname_np "pthread_np.h" HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H)
if (HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H)
add_definitions(-DHAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H=1)
endif()
check_symbol_exists(
pthread_setname_np "pthread_np.h" HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H)
if (HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H)
add_definitions(-DHAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H=1)
endif()
message(STATUS "Checking for pthread_(g/s)etname_np in 'pthread.h':")
check_symbol_exists(pthread_getname_np "pthread.h" HAVE_PTHREAD_GETNAME_NP)
if (HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H)
set(HAVE_PTHREAD_GETNAME_NP 1 CACHE INTERNAL "" FORCE)
endif()
check_symbol_exists(pthread_setname_np "pthread.h" HAVE_PTHREAD_SETNAME_NP)
if (HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H)
set(HAVE_PTHREAD_SETNAME_NP 1 CACHE INTERNAL "" FORCE)
endif()
if (HAVE_PTHREAD_GETNAME_NP)
add_definitions(-DHAVE_PTHREAD_GETNAME_NP=1)
endif()
if (HAVE_PTHREAD_SETNAME_NP)
add_definitions(-DHAVE_PTHREAD_SETNAME_NP=1)
endif()
unset(CMAKE_REQUIRED_DEFINITIONS)
unset(CMAKE_REQUIRED_FLAGS)
endfunction(FindPThreadGetSetName)

View file

@ -0,0 +1,192 @@
#
# SRT - Secure, Reliable, Transport Copyright (c) 2021 Haivision Systems Inc.
#
# This Source Code Form is subject to the terms of the Mozilla Public License,
# v. 2.0. If a copy of the MPL was not distributed with this file, You can
# obtain one at http://mozilla.org/MPL/2.0/.
#
function(ShowProjectConfig)
set(__ssl_configuration)
if (SSL_FOUND OR SSL_LIBRARIES)
set(__ssl_configuration
" SSL Configuration:
SSL_FOUND=${SSL_FOUND}
SSL_INCLUDE_DIRS=${SSL_INCLUDE_DIRS}
SSL_LIBRARIES=${SSL_LIBRARIES}
SSL_VERSION=${SSL_VERSION}\n")
endif()
set(static_property_link_libraries)
if (srt_libspec_static)
get_target_property(
static_property_link_libraries
${TARGET_srt}_static
LINK_LIBRARIES)
endif()
set(shared_property_link_libraries)
if (srt_libspec_shared)
get_target_property(
shared_property_link_libraries
${TARGET_srt}_shared
LINK_LIBRARIES)
endif()
# See https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#id13
set(__more_tc1_config)
if (CMAKE_CROSSCOMPILING)
set(__more_tc1_config
" CMAKE_SYSROOT: ${CMAKE_SYSROOT}\n")
endif()
# See https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#id13
set(__more_tc2_config)
if (APPLE)
set(__more_tc2_config
" CMAKE_INSTALL_NAME_TOOL: ${CMAKE_INSTALL_NAME_TOOL}
CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT}
CMAKE_OSX_ARCHITECTURES: ${CMAKE_OSX_ARCHITECTURES}
CMAKE_OSX_DEPLOYMENT_TARGET: ${CMAKE_OSX_DEPLOYMENT_TARGET}
CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT}\n")
elseif (ANDROID)
set(__more_tc2_config
" CMAKE_ANDROID_NDK: ${CMAKE_ANDROID_NDK}
CMAKE_ANDROID_STANDALONE_TOOLCHAIN: ${CMAKE_ANDROID_STANDALONE_TOOLCHAIN}
CMAKE_ANDROID_API: ${CMAKE_ANDROID_API}
CMAKE_ANDROID_ARCH_ABI: ${CMAKE_ANDROID_ARCH_ABI}
CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION: ${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}
CMAKE_ANDROID_STL_TYPE: ${CMAKE_ANDROID_STL_TYPE}\n")
endif()
message(STATUS
"\n"
"========================================================================\n"
"= Project Configuration:\n"
"========================================================================\n"
" SRT Version:\n"
" SRT_VERSION: ${SRT_VERSION}\n"
" SRT_VERSION_BUILD: ${SRT_VERSION_BUILD}\n"
" CMake Configuration:\n"
" CMAKE_VERSION: ${CMAKE_VERSION}\n"
" CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}\n"
" CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}\n"
" Target Configuration:\n"
" CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}\n"
" CMAKE_SYSTEM_VERSION: ${CMAKE_SYSTEM_VERSION}\n"
" CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}\n"
" CMAKE_SIZEOF_VOID_P: ${CMAKE_SIZEOF_VOID_P}\n"
" DARWIN: ${DARWIN}\n"
" LINUX: ${LINUX}\n"
" BSD: ${BSD}\n"
" MICROSOFT: ${MICROSOFT}\n"
" GNU: ${GNU}\n"
" ANDROID: ${ANDROID}\n"
" SUNOS: ${SUNOS}\n"
" POSIX: ${POSIX}\n"
" SYMLINKABLE: ${SYMLINKABLE}\n"
" APPLE: ${APPLE}\n"
" UNIX: ${UNIX}\n"
" WIN32: ${WIN32}\n"
" MINGW: ${MINGW}\n"
" CYGWIN: ${CYGWIN}\n"
" CYGWIN_USE_POSIX: ${CYGWIN_USE_POSIX}\n"
" Toolchain Configuration:\n"
" CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}\n"
" CMAKE_CROSSCOMPILING: ${CMAKE_CROSSCOMPILING}\n"
"${__more_tc1_config}"
" CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}\n"
" CMAKE_C_COMPILER_VERSION: ${CMAKE_C_COMPILER_VERSION}\n"
" CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}\n"
" CMAKE_C_FLAGS: '${CMAKE_C_FLAGS}'\n"
" CMAKE_C_COMPILE_FEATURES: ${CMAKE_C_COMPILE_FEATURES}\n"
" CMAKE_C_STANDARD: ${CMAKE_CXX_STANDARD}\n"
" CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}\n"
" CMAKE_CXX_COMPILER_VERSION: ${CMAKE_CXX_COMPILER_VERSION}\n"
" CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}\n"
" CMAKE_CXX_FLAGS: '${CMAKE_CXX_FLAGS}'\n"
" CMAKE_CXX_COMPILE_FEATURES: ${CMAKE_CXX_COMPILE_FEATURES}\n"
" CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}\n"
" CMAKE_LINKER: ${CMAKE_LINKER}\n"
#" CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}\n"
#" CMAKE_EXE_LINKER_FLAGS_INIT: ${CMAKE_EXE_LINKER_FLAGS_INIT}\n"
#" CMAKE_MODULE_LINKER_FLAGS: ${CMAKE_MODULE_LINKER_FLAGS}\n"
#" CMAKE_MODULE_LINKER_FLAGS_INIT: ${CMAKE_MODULE_LINKER_FLAGS_INIT}\n"
#" CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}\n"
#" CMAKE_SHARED_LINKER_FLAGS_INIT: ${CMAKE_SHARED_LINKER_FLAGS_INIT}\n"
#" CMAKE_STATIC_LINKER_FLAGS: ${CMAKE_STATIC_LINKER_FLAGS}\n"
#" CMAKE_STATIC_LINKER_FLAGS_INIT: ${CMAKE_STATIC_LINKER_FLAGS_INIT}\n"
" CMAKE_NM: ${CMAKE_NM}\n"
" CMAKE_AR: ${CMAKE_AR}\n"
" CMAKE_RANLIB: ${CMAKE_RANLIB}\n"
"${__more_tc2_config}"
" HAVE_COMPILER_GNU_COMPAT: ${HAVE_COMPILER_GNU_COMPAT}\n"
" CMAKE_THREAD_LIBS: ${CMAKE_THREAD_LIBS}\n"
" CMAKE_THREAD_LIBS_INIT: ${CMAKE_THREAD_LIBS_INIT}\n"
" ENABLE_THREAD_CHECK: ${ENABLE_THREAD_CHECK}\n"
" USE_CXX_STD_APP: ${USE_CXX_STD_APP}\n"
" USE_CXX_STD_LIB: ${USE_CXX_STD_LIB}\n"
" STDCXX: ${STDCXX}\n"
" USE_CXX_STD: ${USE_CXX_STD}\n"
" HAVE_CLOCK_GETTIME_IN: ${HAVE_CLOCK_GETTIME_IN}\n"
" HAVE_CLOCK_GETTIME_LIBRT: ${HAVE_CLOCK_GETTIME_LIBRT}\n"
" HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H: ${HAVE_PTHREAD_GETNAME_NP_IN_PTHREAD_NP_H}\n"
" HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H: ${HAVE_PTHREAD_SETNAME_NP_IN_PTHREAD_NP_H}\n"
" HAVE_PTHREAD_GETNAME_NP: ${HAVE_PTHREAD_GETNAME_NP}\n"
" HAVE_PTHREAD_SETNAME_NP: ${HAVE_PTHREAD_SETNAME_NP}\n"
" HAVE_LIBATOMIC: ${HAVE_LIBATOMIC}\n"
" HAVE_LIBATOMIC_COMPILES: ${HAVE_LIBATOMIC_COMPILES}\n"
" HAVE_LIBATOMIC_COMPILES_STATIC: ${HAVE_LIBATOMIC_COMPILES_STATIC}\n"
" HAVE_GCCATOMIC_INTRINSICS: ${HAVE_GCCATOMIC_INTRINSICS}\n"
" HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC: ${HAVE_GCCATOMIC_INTRINSICS_REQUIRES_LIBATOMIC}\n"
" HAVE_CXX_ATOMIC: ${HAVE_CXX_ATOMIC}\n"
" HAVE_CXX_ATOMIC_STATIC: ${HAVE_CXX_ATOMIC_STATIC}\n"
" HAVE_CXX_STD_PUT_TIME: ${HAVE_CXX_STD_PUT_TIME}\n"
" Project Configuration:\n"
" ENABLE_DEBUG: ${ENABLE_DEBUG}\n"
" ENABLE_CXX11: ${ENABLE_CXX11}\n"
" ENABLE_APPS: ${ENABLE_APPS}\n"
" ENABLE_EXAMPLES: ${ENABLE_EXAMPLES}\n"
" ENABLE_BONDING: ${ENABLE_BONDING}\n"
" ENABLE_TESTING: ${ENABLE_TESTING}\n"
" ENABLE_PROFILE: ${ENABLE_PROFILE}\n"
" ENABLE_LOGGING: ${ENABLE_LOGGING}\n"
" ENABLE_HEAVY_LOGGING: ${ENABLE_HEAVY_LOGGING}\n"
" ENABLE_HAICRYPT_LOGGING: ${ENABLE_HAICRYPT_LOGGING}\n"
" ENABLE_SHARED: ${ENABLE_SHARED}\n"
" ENABLE_STATIC: ${ENABLE_STATIC}\n"
" ENABLE_RELATIVE_LIBPATH: ${ENABLE_RELATIVE_LIBPATH}\n"
" ENABLE_GETNAMEINFO: ${ENABLE_GETNAMEINFO}\n"
" ENABLE_UNITTESTS: ${ENABLE_UNITTESTS}\n"
" ENABLE_ENCRYPTION: ${ENABLE_ENCRYPTION}\n"
" ENABLE_CXX_DEPS: ${ENABLE_CXX_DEPS}\n"
" USE_STATIC_LIBSTDCXX: ${USE_STATIC_LIBSTDCXX}\n"
" ENABLE_INET_PTON: ${ENABLE_INET_PTON}\n"
" ENABLE_CODE_COVERAGE: ${ENABLE_CODE_COVERAGE}\n"
" ENABLE_MONOTONIC_CLOCK: ${ENABLE_MONOTONIC_CLOCK}\n"
" ENABLE_STDCXX_SYNC: ${ENABLE_STDCXX_SYNC}\n"
" USE_OPENSSL_PC: ${USE_OPENSSL_PC}\n"
" OPENSSL_USE_STATIC_LIBS: ${OPENSSL_USE_STATIC_LIBS}\n"
" USE_BUSY_WAITING: ${USE_BUSY_WAITING}\n"
" USE_GNUSTL: ${USE_GNUSTL}\n"
" ENABLE_SOCK_CLOEXEC: ${ENABLE_SOCK_CLOEXEC}\n"
" ENABLE_SHOW_PROJECT_CONFIG: ${ENABLE_SHOW_PROJECT_CONFIG}\n"
" ENABLE_CLANG_TSA: ${ENABLE_CLANG_TSA}\n"
" ATOMIC_USE_SRT_SYNC_MUTEX: ${ATOMIC_USE_SRT_SYNC_MUTEX}\n"
" Constructed Configuration:\n"
" DISABLE_CXX11: ${DISABLE_CXX11}\n"
" HAVE_INET_PTON: ${HAVE_INET_PTON}\n"
" PTHREAD_LIBRARY: ${PTHREAD_LIBRARY}\n"
" USE_ENCLIB: ${USE_ENCLIB}\n"
"${__ssl_configuration}"
" TARGET_srt: ${TARGET_srt}\n"
" srt_libspec_static: ${srt_libspec_static}\n"
" srt_libspec_shared: ${srt_libspec_shared}\n"
" SRT_LIBS_PRIVATE: ${SRT_LIBS_PRIVATE}\n"
" Target Link Libraries:\n"
" Static: ${static_property_link_libraries}\n"
" Shared: ${shared_property_link_libraries}\n"
"========================================================================\n"
)
endfunction(ShowProjectConfig)

View file

@ -0,0 +1,3 @@
## Scripts for building SRT for Android
See [Building SRT for Android](../../docs/build/build-android.md) for the instructions.

View file

@ -0,0 +1,111 @@
#!/bin/sh
echo_help()
{
echo "Usage: $0 [options...]"
echo " -n NDK root path for the build"
echo " -a Target API level"
echo " -t Space-separated list of target architectures"
echo " Android supports the following architectures: armeabi-v7a arm64-v8a x86 x86_64"
echo " -e Encryption library to be used. Possible options: openssl (default) mbedtls"
echo " -o OpenSSL version. E.g. 1.1.1l"
echo " -m Mbed TLS version. E.g. v2.26.0"
echo
echo "Example: ./build-android -n /home/username/Android/Sdk/ndk/23.0.7599858 -a 28 -t \"arm64-v8a x86_64\""
echo
}
# Init optional command line vars
NDK_ROOT=""
API_LEVEL=28
BUILD_TARGETS="armeabi-v7a arm64-v8a x86 x86_64"
OPENSSL_VERSION=1.1.1l
ENC_LIB=openssl
MBEDTLS_VERSION=v2.26.0
while getopts n:a:t:o:s:e:m: option
do
case "${option}"
in
n) NDK_ROOT=${OPTARG};;
a) API_LEVEL=${OPTARG};;
t) BUILD_TARGETS=${OPTARG};;
o) OPENSSL_VERSION=${OPTARG};;
s) SRT_VERSION=${OPTARG};;
e) ENC_LIB=${OPTARG};;
m) MBEDTLS_VERSION=${OPTARG};;
*) twentytwo=${OPTARG};;
esac
done
echo_help
if [ -z "$NDK_ROOT" ] ; then
echo "NDK directory not set."
exit 128
else
if [ ! -d "$NDK_ROOT" ]; then
echo "NDK directory does not exist: $NDK_ROOT"
exit 128
fi
fi
SCRIPT_DIR=$(pwd)
HOST_TAG='unknown'
unamestr=$(uname -s)
if [ "$unamestr" = 'Linux' ]; then
HOST_TAG='linux-x86_64'
elif [ "$unamestr" = 'Darwin' ]; then
if [ $(uname -p) = 'arm' ]; then
echo "NDK does not currently support ARM64"
exit 128
else
HOST_TAG='darwin-x86_64'
fi
fi
# Write files relative to current location
BASE_DIR=$(pwd)
case "${BASE_DIR}" in
*\ * )
echo "Your path contains whitespaces, which is not supported by 'make install'."
exit 128
;;
esac
cd "${BASE_DIR}"
if [ $ENC_LIB = 'openssl' ]; then
echo "Building OpenSSL $OPENSSL_VERSION"
$SCRIPT_DIR/mkssl -n $NDK_ROOT -a $API_LEVEL -t "$BUILD_TARGETS" -o $OPENSSL_VERSION -d $BASE_DIR -h $HOST_TAG
elif [ $ENC_LIB = 'mbedtls' ]; then
if [ ! -d $BASE_DIR/mbedtls ]; then
git clone https://github.com/ARMmbed/mbedtls mbedtls
if [ ! -z "$MBEDTLS_VERSION" ]; then
git -C $BASE_DIR/mbedtls checkout $MBEDTLS_VERSION
fi
fi
else
echo "Unknown encryption library. Possible options: openssl mbedtls"
exit 128
fi
# Build working copy of srt repository
REPO_DIR="../.."
for build_target in $BUILD_TARGETS; do
LIB_DIR=$BASE_DIR/$build_target/lib
JNI_DIR=$BASE_DIR/prebuilt/$build_target
mkdir -p $JNI_DIR
if [ $ENC_LIB = 'mbedtls' ]; then
$SCRIPT_DIR/mkmbedtls -n $NDK_ROOT -a $API_LEVEL -t $build_target -s $BASE_DIR/mbedtls -i $BASE_DIR/$build_target
cp $LIB_DIR/libmbedcrypto.so $JNI_DIR/libmbedcrypto.so
cp $LIB_DIR/libmbedtls.so $JNI_DIR/libmbedtls.so
cp $LIB_DIR/libmbedx509.so $JNI_DIR/libmbedx509.so
fi
git -C $REPO_DIR clean -fd -e scripts
$SCRIPT_DIR/mksrt -n $NDK_ROOT -a $API_LEVEL -t $build_target -e $ENC_LIB -s $REPO_DIR -i $BASE_DIR/$build_target
cp $LIB_DIR/libsrt.so $JNI_DIR/libsrt.so
done

View file

@ -0,0 +1,27 @@
#!/bin/sh
while getopts s:i:t:n:a: option
do
case "${option}"
in
s) SRC_DIR=${OPTARG};;
i) INSTALL_DIR=${OPTARG};;
t) ARCH_ABI=${OPTARG};;
n) NDK_ROOT=${OPTARG};;
a) API_LEVEL=${OPTARG};;
*) twentytwo=${OPTARG};;
esac
done
BUILD_DIR=/tmp/mbedtls_android_build
rm -rf $BUILD_DIR
mkdir $BUILD_DIR
cd $BUILD_DIR
cmake -DENABLE_TESTING=Off -DUSE_SHARED_MBEDTLS_LIBRARY=On \
-DCMAKE_PREFIX_PATH=$INSTALL_DIR -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR -DCMAKE_ANDROID_NDK=$NDK_ROOT \
-DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=$API_LEVEL -DCMAKE_ANDROID_ARCH_ABI=$ARCH_ABI \
-DCMAKE_C_FLAGS="-fPIC" -DCMAKE_SHARED_LINKER_FLAGS="-Wl,--build-id" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo $SRC_DIR
cmake --build .
cmake --install .

View file

@ -0,0 +1,32 @@
#!/bin/sh
while getopts s:i:t:n:a:e: option
do
case "${option}"
in
s) SRC_DIR=${OPTARG};;
i) INSTALL_DIR=${OPTARG};;
t) ARCH_ABI=${OPTARG};;
n) NDK_ROOT=${OPTARG};;
a) API_LEVEL=${OPTARG};;
e) ENC_LIB=${OPTARG};;
*) twentytwo=${OPTARG};;
esac
done
cd $SRC_DIR
./configure --use-enclib=$ENC_LIB \
--use-openssl-pc=OFF \
--OPENSSL_INCLUDE_DIR=$INSTALL_DIR/include \
--OPENSSL_CRYPTO_LIBRARY=$INSTALL_DIR/lib/libcrypto.a --OPENSSL_SSL_LIBRARY=$INSTALL_DIR/lib/libssl.a \
--STATIC_MBEDTLS=FALSE \
--MBEDTLS_INCLUDE_DIR=$INSTALL_DIR/include --MBEDTLS_INCLUDE_DIRS=$INSTALL_DIR/include \
--MBEDTLS_LIBRARIES=$INSTALL_DIR/lib/libmbedtls.so \
--CMAKE_PREFIX_PATH=$INSTALL_DIR --CMAKE_INSTALL_PREFIX=$INSTALL_DIR --CMAKE_ANDROID_NDK=$NDK_ROOT \
--CMAKE_SYSTEM_NAME=Android --CMAKE_SYSTEM_VERSION=$API_LEVEL --CMAKE_ANDROID_ARCH_ABI=$ARCH_ABI \
--CMAKE_C_FLAGS="-fPIC" --CMAKE_SHARED_LINKER_FLAGS="-Wl,--build-id" \
--enable-c++11 --enable-stdcxx-sync \
--enable-debug=2 --enable-logging=0 --enable-heavy-logging=0 --enable-apps=0
make
make install

View file

@ -0,0 +1,85 @@
#!/bin/sh
while getopts n:o:a:t:d:h: option
do
case "${option}"
in
n) ANDROID_NDK=${OPTARG};;
o) OPENSSL_VERSION=${OPTARG};;
a) API_LEVEL=${OPTARG};;
t) BUILD_TARGETS=${OPTARG};;
d) OUT_DIR=${OPTARG};;
h) HOST_TAG=${OPTARG};;
*) twentytwo=${OPTARG};;
esac
done
BUILD_DIR=/tmp/openssl_android_build
if [ ! -d openssl-${OPENSSL_VERSION} ]
then
if [ ! -f openssl-${OPENSSL_VERSION}.tar.gz ]
then
wget https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz || exit 128
fi
tar xzf openssl-${OPENSSL_VERSION}.tar.gz || exit 128
fi
cd openssl-${OPENSSL_VERSION} || exit 128
##### export ndk directory. Required by openssl-build-scripts #####
case ${OPENSSL_VERSION} in
1.1.1*)
export ANDROID_NDK_HOME=$ANDROID_NDK
;;
*)
export ANDROID_NDK_ROOT=$ANDROID_NDK
;;
esac
export PATH=$ANDROID_NDK/toolchains/llvm/prebuilt/$HOST_TAG/bin:$PATH
##### build-function #####
build_the_thing() {
make clean
./Configure $SSL_TARGET -D__ANDROID_API__=$API_LEVEL && \
make SHLIB_EXT=.so && \
make install SHLIB_EXT=.so DESTDIR=$DESTDIR || exit 128
}
##### set variables according to build-tagret #####
for build_target in $BUILD_TARGETS
do
case $build_target in
armeabi-v7a)
DESTDIR="$BUILD_DIR/armeabi-v7a"
SSL_TARGET="android-arm"
;;
x86)
DESTDIR="$BUILD_DIR/x86"
SSL_TARGET="android-x86"
;;
x86_64)
DESTDIR="$BUILD_DIR/x86_64"
SSL_TARGET="android-x86_64"
;;
arm64-v8a)
DESTDIR="$BUILD_DIR/arm64-v8a"
SSL_TARGET="android-arm64"
;;
esac
rm -rf $DESTDIR
build_the_thing
#### copy libraries and includes to output-directory #####
mkdir -p $OUT_DIR/$build_target/include
cp -R $DESTDIR/usr/local/include/* $OUT_DIR/$build_target/include
cp -R $DESTDIR/usr/local/ssl/* $OUT_DIR/$build_target/
mkdir -p $OUT_DIR/$build_target/lib
cp -R $DESTDIR/usr/local/lib/*.so $OUT_DIR/$build_target/lib
cp -R $DESTDIR/usr/local/lib/*.a $OUT_DIR/$build_target/lib
done
echo Success

View file

@ -0,0 +1,3 @@
@ECHO OFF
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\PowerShell.exe -Command "& '%~dpn0.ps1'"
pause

View file

@ -0,0 +1,238 @@
################################################################################
# Windows SRT Build Script
#============================
# Usable on a Windows PC with Powershell and Visual studio,
# or called by CI systems like AppVeyor
#
# By default produces a VS2019 64-bit Release binary using C++11 threads, without
# encryption or unit tests enabled, but including test apps.
# Before enabling any encryption options, install OpenSSL or set VCKPG flag to build
################################################################################
param (
[Parameter()][String]$VS_VERSION = "2019",
[Parameter()][String]$CONFIGURATION = "Release",
[Parameter()][String]$DEVENV_PLATFORM = "x64",
[Parameter()][String]$ENABLE_ENCRYPTION = "OFF",
[Parameter()][String]$STATIC_LINK_SSL = "OFF",
[Parameter()][String]$CXX11 = "ON",
[Parameter()][String]$BUILD_APPS = "ON",
[Parameter()][String]$UNIT_TESTS = "OFF",
[Parameter()][String]$BUILD_DIR = "_build",
[Parameter()][String]$VCPKG_OPENSSL = "OFF",
[Parameter()][String]$BONDING = "OFF"
)
# cmake can be optionally installed (useful when running interactively on a developer station).
# The URL for automatic download is defined later in the script, but it should be possible to just vary the
# specific version set below and the URL should be stable enough to still work - you have been warned.
$cmakeVersion = "3.23.2"
# make all errors trigger a script stop, rather than just carry on
$ErrorActionPreference = "Stop"
$projectRoot = Join-Path $PSScriptRoot "/.." -Resolve
# if running within AppVeyor, use environment variables to set params instead of passed-in values
if ( $Env:APPVEYOR ) {
if ( $Env:PLATFORM -eq 'x86' ) { $DEVENV_PLATFORM = 'Win32' } else { $DEVENV_PLATFORM = 'x64' }
if ( $Env:APPVEYOR_BUILD_WORKER_IMAGE -eq 'Visual Studio 2019' ) { $VS_VERSION='2019' }
if ( $Env:APPVEYOR_BUILD_WORKER_IMAGE -eq 'Visual Studio 2015' ) { $VS_VERSION='2015' }
if ( $Env:APPVEYOR_BUILD_WORKER_IMAGE -eq 'Visual Studio 2013' ) { $VS_VERSION='2013' }
#if not statically linking OpenSSL, set flag to gather the specific openssl package from the build server into package
if ( $STATIC_LINK_SSL -eq 'OFF' ) { $Env:GATHER_SSL_INTO_PACKAGE = $true }
#if unit tests are on, set flag to actually execute ctest step
if ( $UNIT_TESTS -eq 'ON' ) { $Env:RUN_UNIT_TESTS = $true }
$CONFIGURATION = $Env:CONFIGURATION
#appveyor has many openssl installations - place the latest one in the default location unless VS2013
if( $VS_VERSION -ne '2013' ) {
Remove-Item -Path "C:\OpenSSL-Win32" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
Remove-Item -Path "C:\OpenSSL-Win64" -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
Copy-Item -Path "C:\OpenSSL-v111-Win32" "C:\OpenSSL-Win32" -Recurse | Out-Null
Copy-Item -Path "C:\OpenSSL-v111-Win64" "C:\OpenSSL-Win64" -Recurse | Out-Null
}
}
# persist VS_VERSION so it can be used in an artifact name later
$Env:VS_VERSION = $VS_VERSION
# select the appropriate cmake generator string given the environment
if ( $VS_VERSION -eq '2019' ) { $CMAKE_GENERATOR = 'Visual Studio 16 2019'; $MSBUILDVER = "16.0"; }
if ( $VS_VERSION -eq '2015' -and $DEVENV_PLATFORM -eq 'Win32' ) { $CMAKE_GENERATOR = 'Visual Studio 14 2015'; $MSBUILDVER = "14.0"; }
if ( $VS_VERSION -eq '2015' -and $DEVENV_PLATFORM -eq 'x64' ) { $CMAKE_GENERATOR = 'Visual Studio 14 2015 Win64'; $MSBUILDVER = "14.0"; }
if ( $VS_VERSION -eq '2013' -and $DEVENV_PLATFORM -eq 'Win32' ) { $CMAKE_GENERATOR = 'Visual Studio 12 2013'; $MSBUILDVER = "12.0"; }
if ( $VS_VERSION -eq '2013' -and $DEVENV_PLATFORM -eq 'x64' ) { $CMAKE_GENERATOR = 'Visual Studio 12 2013 Win64'; $MSBUILDVER = "12.0"; }
# clear any previous build and create & enter the build directory
$buildDir = Join-Path "$projectRoot" "$BUILD_DIR"
Write-Output "Creating (or cleaning if already existing) the folder $buildDir for project files and outputs"
Remove-Item -Path $buildDir -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
New-Item -ItemType Directory -Path $buildDir -ErrorAction SilentlyContinue | Out-Null
Push-Location $buildDir
# check cmake is installed
if ( $null -eq (Get-Command "cmake.exe" -ErrorAction SilentlyContinue) ) {
$installCmake = Read-Host "Unable to find cmake in your PATH - would you like to download and install automatically? [yes/no]"
if ( $installCmake -eq "y" -or $installCmake -eq "yes" ) {
# download cmake and run MSI for user
$client = New-Object System.Net.WebClient
$tempDownloadFile = New-TemporaryFile
$cmakeUrl = "https://github.com/Kitware/CMake/releases/download/v$cmakeVersion/cmake-$cmakeVersion-win64-x64.msi"
$cmakeMsiFile = "$tempDownloadFile.cmake-$cmakeVersion-win64-x64.msi"
Write-Output "Downloading cmake from $cmakeUrl (temporary file location $cmakeMsiFile)"
Write-Output "Note: select the option to add cmake to path for this script to operate"
$client.DownloadFile("$cmakeUrl", "$cmakeMsiFile")
Start-Process $cmakeMsiFile -Wait
Remove-Item $cmakeMsiFile
Write-Output "Cmake should have installed, this script will now exit because of path updates - please now re-run this script"
throw
}
else{
Write-Output "Quitting because cmake is required"
throw
}
}
# get pthreads from nuget if CXX11 is not enabled
if ( $CXX11 -eq "OFF" ) {
# get pthreads (this is legacy, and is only available in nuget for VS2015 and VS2013)
if ( $VS_VERSION -gt 2015 ) {
Write-Output "Pthreads is not recommended for use beyond VS2015 and is not supported by this build script - aborting build"
throw
}
if ( $DEVENV_PLATFORM -eq 'Win32' ) {
nuget install cinegy.pthreads-win32-$VS_VERSION -version 2.9.1.24 -OutputDirectory ../_packages
}
else {
nuget install cinegy.pthreads-win64-$VS_VERSION -version 2.9.1.24 -OutputDirectory ../_packages
}
}
# check to see if static SSL linking was requested, and enable encryption if not already ON
if ( $STATIC_LINK_SSL -eq "ON" ) {
if ( $ENABLE_ENCRYPTION -eq "OFF" ) {
# requesting a static link implicitly requires encryption support
Write-Output "Static linking to OpenSSL requested, will force encryption feature ON"
$ENABLE_ENCRYPTION = "ON"
}
}
# check to see if VCPKG is marked to provide OpenSSL, and enable encryption if not already ON
if ( $VCPKG_OPENSSL -eq "ON" ) {
if ( $ENABLE_ENCRYPTION -eq "OFF" ) {
# requesting VCPKG to provide OpenSSL requires encryption support
Write-Output "VCPKG compilation of OpenSSL requested, will force encryption feature ON"
$ENABLE_ENCRYPTION = "ON"
}
}
# build the cmake command flags from arguments
$cmakeFlags = "-DCMAKE_BUILD_TYPE=$CONFIGURATION " +
"-DENABLE_STDCXX_SYNC=$CXX11 " +
"-DENABLE_APPS=$BUILD_APPS " +
"-DENABLE_ENCRYPTION=$ENABLE_ENCRYPTION " +
"-DENABLE_BONDING=$BONDING " +
"-DENABLE_UNITTESTS=$UNIT_TESTS"
# if VCPKG is flagged to provide OpenSSL, checkout VCPKG and install package
if ( $VCPKG_OPENSSL -eq 'ON' ) {
Push-Location $projectRoot
Write-Output "Cloning VCPKG into: $(Get-Location)"
if (Test-Path -Path ".\vcpkg") {
Set-Location .\vcpkg
git pull
} else {
git clone https://github.com/microsoft/vcpkg
Set-Location .\vcpkg
}
.\bootstrap-vcpkg.bat
if($DEVENV_PLATFORM -EQ "x64"){
if($STATIC_LINK_SSL -EQ "ON"){
.\vcpkg install openssl:x64-windows-static
$cmakeFlags += " -DVCPKG_TARGET_TRIPLET=x64-windows-static"
}
else{
.\vcpkg install openssl:x64-windows
}
}
else{
if($STATIC_LINK_SSL -EQ "ON"){
.\vcpkg install openssl:x86-windows-static
$cmakeFlags += " -DVCPKG_TARGET_TRIPLET=x86-windows-static"
}
else{
.\vcpkg install openssl:x86-windows
}
}
.\vcpkg integrate install
Pop-Location
$cmakeFlags += " -DCMAKE_TOOLCHAIN_FILE=$projectRoot\vcpkg\scripts\buildsystems\vcpkg.cmake"
}
else {
$cmakeFlags += " -DOPENSSL_USE_STATIC_LIBS=$STATIC_LINK_SSL "
}
# cmake uses a flag for architecture from vs2019, so add that as a suffix
if ( $VS_VERSION -eq '2019' ) {
$cmakeFlags += " -A `"$DEVENV_PLATFORM`""
}
# fire cmake to build project files
$execVar = "cmake ../ -G`"$CMAKE_GENERATOR`" $cmakeFlags"
Write-Output $execVar
# Reset reaction to Continue for cmake as it sometimes tends to print
# things on stderr, which is understood by PowerShell as error. The
# exit code from cmake will be checked anyway.
$ErrorActionPreference = "Continue"
Invoke-Expression "& $execVar"
# check build ran OK, exit if cmake failed
if( $LASTEXITCODE -ne 0 ) {
Write-Output "Non-zero exit code from cmake: $LASTEXITCODE"
throw
}
$ErrorActionPreference = "Stop"
# run the set-version-metadata script to inject build numbers into appveyors console and the resulting DLL
. $PSScriptRoot/set-version-metadata.ps1
# look for msbuild
$msBuildPath = Get-Command "msbuild.exe" -ErrorAction SilentlyContinue
if ( $null -eq $msBuildPath ) {
# no mbsuild in the path, so try to locate with 'vswhere'
$vsWherePath = Get-Command "vswhere.exe" -ErrorAction SilentlyContinue
if ( $null -eq $vsWherePath ) {
# no vswhere in the path, so check the Microsoft published location (true since VS2017 Update 2)
$vsWherePath = Get-Command "${Env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -ErrorAction SilentlyContinue
if ( $null -eq $vsWherePath ) {
Write-Output "Cannot find vswhere (used to locate msbuild). Please install VS2017 update 2 (or later) or add vswhere to your path and try again"
throw
}
}
$msBuildPath = & $vsWherePath -products * -version $MSBUILDVER -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe | select-object -first 1
if ( $null -eq $msBuildPath ) {
Write-Output "vswhere.exe cannot find msbuild for the specified Visual Studio version - please check the installation"
throw
}
}
& $msBuildPath SRT.sln -m /p:Configuration=$CONFIGURATION /p:Platform=$DEVENV_PLATFORM
# return to the directory previously occupied before running the script
Pop-Location
# if msbuild returned non-zero, throw to cause failure in CI
if( $LASTEXITCODE -ne 0 ) {
throw
}

View file

@ -0,0 +1,7 @@
#!/bin/bash
shopt -s globstar
gcov_data_dir="."
for x in ./**/*.o; do
echo "x: $x"
gcov "$gcov_data_dir/$x"
done

View file

@ -15,7 +15,9 @@ md %APPVEYOR_BUILD_FOLDER%\package\include
md %APPVEYOR_BUILD_FOLDER%\package\include\win
md %APPVEYOR_BUILD_FOLDER%\package\bin
md %APPVEYOR_BUILD_FOLDER%\package\lib
md %APPVEYOR_BUILD_FOLDER%\package\openssl-win%FOLDER_PLATFORM%
IF "%GATHER_SSL_INTO_PACKAGE%"=="True" (
md %APPVEYOR_BUILD_FOLDER%\package\openssl-win%FOLDER_PLATFORM%
)
rem Gather SRT includes, binaries and libs
copy %APPVEYOR_BUILD_FOLDER%\version.h %APPVEYOR_BUILD_FOLDER%\package\include\
@ -23,13 +25,13 @@ copy %APPVEYOR_BUILD_FOLDER%\srtcore\*.h %APPVEYOR_BUILD_FOLDER%\package\include
copy %APPVEYOR_BUILD_FOLDER%\haicrypt\*.h %APPVEYOR_BUILD_FOLDER%\package\include\
copy %APPVEYOR_BUILD_FOLDER%\common\*.h %APPVEYOR_BUILD_FOLDER%\package\include\
copy %APPVEYOR_BUILD_FOLDER%\common\win\*.h %APPVEYOR_BUILD_FOLDER%\package\include\win\
copy %APPVEYOR_BUILD_FOLDER%\%CONFIGURATION%\*.exe %APPVEYOR_BUILD_FOLDER%\package\bin\
copy %APPVEYOR_BUILD_FOLDER%\%CONFIGURATION%\*.dll %APPVEYOR_BUILD_FOLDER%\package\bin\
copy %APPVEYOR_BUILD_FOLDER%\%CONFIGURATION%\*.lib %APPVEYOR_BUILD_FOLDER%\package\lib\
IF "%CONFIGURATION%"=="Debug" (
copy %APPVEYOR_BUILD_FOLDER%\%CONFIGURATION%\*.pdb %APPVEYOR_BUILD_FOLDER%\package\bin\
)
copy %APPVEYOR_BUILD_FOLDER%\_build\%CONFIGURATION%\*.exe %APPVEYOR_BUILD_FOLDER%\package\bin\
copy %APPVEYOR_BUILD_FOLDER%\_build\%CONFIGURATION%\*.dll %APPVEYOR_BUILD_FOLDER%\package\bin\
copy %APPVEYOR_BUILD_FOLDER%\_build\%CONFIGURATION%\*.lib %APPVEYOR_BUILD_FOLDER%\package\lib\
copy %APPVEYOR_BUILD_FOLDER%\_build\%CONFIGURATION%\*.pdb %APPVEYOR_BUILD_FOLDER%\package\bin\
rem gather 3rd party openssl elements
(robocopy c:\openssl-win%FOLDER_PLATFORM%\ %APPVEYOR_BUILD_FOLDER%\package\openssl-win%FOLDER_PLATFORM% /s /e /np) ^& IF %ERRORLEVEL% GTR 1 exit %ERRORLEVEL%
rem Gather 3rd party openssl elements
IF "%GATHER_SSL_INTO_PACKAGE%"=="True" (
(robocopy c:\openssl-win%FOLDER_PLATFORM%\ %APPVEYOR_BUILD_FOLDER%\package\openssl-win%FOLDER_PLATFORM% /s /e /np) ^& IF %ERRORLEVEL% GTR 1 exit %ERRORLEVEL%
)
exit 0

View file

@ -0,0 +1,251 @@
#!/usr/bin/tclsh
#*
#* SRT - Secure, Reliable, Transport
#* Copyright (c) 2020 Haivision Systems Inc.
#*
#* This Source Code Form is subject to the terms of the Mozilla Public
#* License, v. 2.0. If a copy of the MPL was not distributed with this
#* file, You can obtain one at http://mozilla.org/MPL/2.0/.
#*
#*/
#
#*****************************************************************************
#written by
# Haivision Systems Inc.
#*****************************************************************************
set code_major {
UNKNOWN -1
SUCCESS 0
SETUP 1
CONNECTION 2
SYSTEMRES 3
FILESYSTEM 4
NOTSUP 5
AGAIN 6
PEERERROR 7
}
set code_minor {
NONE 0
TIMEOUT 1
REJECTED 2
NORES 3
SECURITY 4
CLOSED 5
CONNLOST 1
NOCONN 2
THREAD 1
MEMORY 2
OBJECT 3
SEEKGFAIL 1
READFAIL 2
SEEKPFAIL 3
WRITEFAIL 4
ISBOUND 1
ISCONNECTED 2
INVAL 3
SIDINVAL 4
ISUNBOUND 5
NOLISTEN 6
ISRENDEZVOUS 7
ISRENDUNBOUND 8
INVALMSGAPI 9
INVALBUFFERAPI 10
BUSY 11
XSIZE 12
EIDINVAL 13
EEMPTY 14
BUSYPORT 15
WRAVAIL 1
RDAVAIL 2
XMTIMEOUT 3
CONGESTION 4
}
set errortypes {
SUCCESS "Success" {
NONE ""
}
SETUP "Connection setup failure" {
NONE ""
TIMEOUT "connection timed out"
REJECTED "connection rejected"
NORES "unable to create/configure SRT socket"
SECURITY "aborted for security reasons"
CLOSED "socket closed during operation"
}
CONNECTION "" {
NONE ""
CONNLOST "Connection was broken"
NOCONN "Connection does not exist"
}
SYSTEMRES "System resource failure" {
NONE ""
THREAD "unable to create new threads"
MEMORY "unable to allocate buffers"
OBJECT "unable to allocate a system object"
}
FILESYSTEM "File system failure" {
NONE ""
SEEKGFAIL "cannot seek read position"
READFAIL "failure in read"
SEEKPFAIL "cannot seek write position"
WRITEFAIL "failure in write"
}
NOTSUP "Operation not supported" {
NONE ""
ISBOUND "Cannot do this operation on a BOUND socket"
ISCONNECTED "Cannot do this operation on a CONNECTED socket"
INVAL "Bad parameters"
SIDINVAL "Invalid socket ID"
ISUNBOUND "Cannot do this operation on an UNBOUND socket"
NOLISTEN "Socket is not in listening state"
ISRENDEZVOUS "Listen/accept is not supported in rendezvous connection setup"
ISRENDUNBOUND "Cannot call connect on UNBOUND socket in rendezvous connection setup"
INVALMSGAPI "Incorrect use of Message API (sendmsg/recvmsg)."
INVALBUFFERAPI "Incorrect use of Buffer API (send/recv) or File API (sendfile/recvfile)."
BUSY "Another socket is already listening on the same port"
XSIZE "Message is too large to send (it must be less than the SRT send buffer size)"
EIDINVAL "Invalid epoll ID"
EEMPTY "All sockets removed from epoll, waiting would deadlock"
BUSYPORT "Another socket is bound to that port and is not reusable for requested settings"
}
AGAIN "Non-blocking call failure" {
NONE ""
WRAVAIL "no buffer available for sending"
RDAVAIL "no data available for reading"
XMTIMEOUT "transmission timed out"
CONGESTION "early congestion notification"
}
PEERERROR "The peer side has signaled an error" {
NONE ""
}
}
set main_array_item {
const char** strerror_array_major [] = {
$minor_array_list
};
}
set major_size_item {
const size_t strerror_array_sizes [] = {
$minor_array_sizes
};
}
set minor_array_item {
const char* strerror_msgs_$majorlc [] = {
$minor_message_items
};
}
set strerror_function {
const char* strerror_get_message(size_t major, size_t minor)
{
static const char* const undefined = "UNDEFINED ERROR";
// Extract the major array
if (major >= sizeof(strerror_array_major)/sizeof(const char**))
{
return undefined;
}
const char** array = strerror_array_major[major];
size_t size = strerror_array_sizes[major];
if (minor >= size)
{
return undefined;
}
return array[minor];
}
}
set globalheader {
/*
WARNING: Generated from ../scripts/generate-error-types.tcl
DO NOT MODIFY.
Copyright applies as per the generator script.
*/
#include <cstddef>
}
proc Generate:imp {} {
puts $::globalheader
puts "namespace srt\n\{"
# Generate major array
set majitem 0
set minor_array_sizes ""
foreach {mt mm cont} $::errortypes {
puts "// MJ_$mt '$mm'"
# Generate minor array
set majorlc [string tolower $mt]
set minor_message_items ""
set minitem 0
foreach {mnt mnm} $cont {
if {$mm == ""} {
set msg $mnm
} elseif {$mnm == ""} {
set msg $mm
} else {
set msg "$mm: $mnm"
}
append minor_message_items " \"$msg\", // MN_$mnt = $minitem\n"
incr minitem
}
append minor_message_items " \"\""
puts [subst -nobackslashes -nocommands $::minor_array_item]
append minor_array_list " strerror_msgs_$majorlc, // MJ_$mt = $majitem\n"
#append minor_array_sizes " [expr {$minitem}],\n"
append minor_array_sizes " SRT_ARRAY_SIZE(strerror_msgs_$majorlc) - 1,\n"
incr majitem
}
append minor_array_list " NULL"
append minor_array_sizes " 0"
puts [subst -nobackslashes -nocommands $::main_array_item]
puts {#define SRT_ARRAY_SIZE(ARR) sizeof(ARR) / sizeof(ARR[0])}
puts [subst -nobackslashes -nocommands $::major_size_item]
puts $::strerror_function
puts "\} // namespace srt"
}
set defmode imp
if {[lindex $argv 0] != ""} {
set defmode [lindex $argv 0]
}
Generate:$defmode

View file

@ -0,0 +1,454 @@
#!/usr/bin/tclsh
#*
#* SRT - Secure, Reliable, Transport
#* Copyright (c) 2020 Haivision Systems Inc.
#*
#* This Source Code Form is subject to the terms of the Mozilla Public
#* License, v. 2.0. If a copy of the MPL was not distributed with this
#* file, You can obtain one at http://mozilla.org/MPL/2.0/.
#*
#*/
#
#*****************************************************************************
#written by
# Haivision Systems Inc.
#*****************************************************************************
# What fields are there in every entry
set model {
longname
shortname
id
description
}
# Logger definitions.
# Comments here allowed, just only for the whole line.
# Use values greater than 0. Value 0 is reserved for LOGFA_GENERAL,
# which is considered always enabled.
set loggers {
GENERAL gg 0 "General uncategorized log, for serious issues only"
SOCKMGMT sm 1 "Socket create/open/close/configure activities"
CONN cn 2 "Connection establishment and handshake"
XTIMER xt 3 "The checkTimer and around activities"
TSBPD ts 4 "The TsBPD thread"
RSRC rs 5 "System resource allocation and management"
CONGEST cc 7 "Congestion control module"
PFILTER pf 8 "Packet filter module"
API_CTRL ac 11 "API part for socket and library managmenet"
QUE_CTRL qc 13 "Queue control activities"
EPOLL_UPD ei 16 "EPoll, internal update activities"
API_RECV ar 21 "API part for receiving"
BUF_RECV br 22 "Buffer, receiving side"
QUE_RECV qr 23 "Queue, receiving side"
CHN_RECV kr 24 "CChannel, receiving side"
GRP_RECV gr 25 "Group, receiving side"
API_SEND as 31 "API part for sending"
BUF_SEND bs 32 "Buffer, sending side"
QUE_SEND qs 33 "Queue, sending side"
CHN_SEND ks 34 "CChannel, sending side"
GRP_SEND gs 35 "Group, sending side"
INTERNAL in 41 "Internal activities not connected directly to a socket"
QUE_MGMT qm 43 "Queue, management part"
CHN_MGMT km 44 "CChannel, management part"
GRP_MGMT gm 45 "Group, management part"
EPOLL_API ea 46 "EPoll, API part"
}
set hidden_loggers {
# Haicrypt logging - usually off.
HAICRYPT hc 6 "Haicrypt module area"
# defined in apps, this is only a stub to lock the value
APPLOG ap 10 "Applications"
}
set globalheader {
/*
WARNING: Generated from ../scripts/generate-logging-defs.tcl
DO NOT MODIFY.
Copyright applies as per the generator script.
*/
}
# This defines, what kind of definition will be generated
# for a given file out of the log FA entry list.
# Fields:
# - prefix/postfix model
# - logger_format
# - hidden_logger_format
# COMMENTS NOT ALLOWED HERE! Only as C++ comments inside C++ model code.
set special {
srtcore/logger_default.cpp {
if {"$longname" == "HAICRYPT"} {
puts $od "
#if ENABLE_HAICRYPT_LOGGING
allfa.set(SRT_LOGFA_HAICRYPT, true);
#endif"
}
}
}
proc GenerateModelForSrtH {} {
# `path` will be set to the git top path
global path
set fd [open [file join $path srtcore/srt.h] r]
set contents ""
set state read
set pass looking
while { [gets $fd line] != -1 } {
if { $state == "read" } {
if { $pass != "passed" } {
set re [regexp {SRT_LOGFA BEGIN GENERATED SECTION} $line]
if {$re} {
set state skip
set pass found
}
}
append contents "$line\n"
continue
}
if {$state == "skip"} {
if { [string trim $line] == "" } {
# Empty line, continue skipping
continue
}
set re [regexp {SRT_LOGFA END GENERATED SECTION} $line]
if {!$re} {
# Still SRT_LOGFA definitions
continue
}
# End of generated section. Switch back to pass-thru.
# First fill the gap
append contents "\n\$entries\n\n"
append contents "$line\n"
set state read
set pass passed
}
}
close $fd
# Sanity check
if {$pass != "passed"} {
error "Invalid contents of `srt.h` file, can't find '#define SRT_LOGFA_' phrase"
}
return $contents
}
# COMMENTS NOT ALLOWED HERE! Only as C++ comments inside C++ model code.
# (NOTE: Tcl syntax highlighter will likely falsely highlight # as comment here)
#
# Model: TARGET-NAME { format-model logger-pattern hidden-logger-pattern }
#
# Special syntax:
#
# %<command> : a high-level command execution. This declares a command that
# must be executed to GENERATE the model. Then, [subst] is executed
# on the results.
#
# = : when placed as the hidden-logger-pattern, it's equal to logger-pattern.
#
set generation {
srtcore/srt.h {
{%GenerateModelForSrtH}
{#define [format "%-20s %-3d" SRT_LOGFA_${longname} $id] // ${shortname}log: $description}
=
}
srtcore/logger_default.cpp {
{
$globalheader
#include "srt.h"
#include "logging.h"
#include "logger_defs.h"
namespace srt_logging
{
AllFaOn::AllFaOn()
{
$entries
}
} // namespace srt_logging
}
{
allfa.set(SRT_LOGFA_${longname}, true);
}
}
srtcore/logger_defs.cpp {
{
$globalheader
#include "srt.h"
#include "logging.h"
#include "logger_defs.h"
namespace srt_logging { AllFaOn logger_fa_all; }
// We need it outside the namespace to preserve the global name.
// It's a part of "hidden API" (used by applications)
SRT_API srt_logging::LogConfig srt_logger_config(srt_logging::logger_fa_all.allfa);
namespace srt_logging
{
$entries
} // namespace srt_logging
}
{
Logger ${shortname}log(SRT_LOGFA_${longname}, srt_logger_config, "SRT.${shortname}");
}
}
srtcore/logger_defs.h {
{
$globalheader
#ifndef INC_SRT_LOGGER_DEFS_H
#define INC_SRT_LOGGER_DEFS_H
#include "srt.h"
#include "logging.h"
namespace srt_logging
{
struct AllFaOn
{
LogConfig::fa_bitset_t allfa;
AllFaOn();
};
$entries
} // namespace srt_logging
#endif
}
{
extern Logger ${shortname}log;
}
}
apps/logsupport_appdefs.cpp {
{
$globalheader
#include "logsupport.hpp"
LogFANames::LogFANames()
{
$entries
}
}
{
Install("$longname", SRT_LOGFA_${longname});
}
{
Install("$longname", SRT_LOGFA_${longname});
}
}
}
# EXECUTION
set here [file dirname [file normalize $argv0]]
if {[lindex [file split $here] end] != "scripts"} {
puts stderr "The script is in weird location."
exit 1
}
set path [file join {*}[lrange [file split $here] 0 end-1]]
# Utility. Allows to put line-oriented comments and have empty lines
proc no_comments {input} {
set output ""
foreach line [split $input \n] {
set nn [string trim $line]
if { $nn == "" || [string index $nn 0] == "#" } {
continue
}
append output $line\n
}
return $output
}
proc generate_file {od target} {
global globalheader
lassign [dict get $::generation $target] format_model pattern hpattern
set ptabprefix ""
if {[string index $format_model 0] == "%"} {
set command [string range $format_model 1 end]
set format_model [eval $command]
}
if {$format_model != ""} {
set beginindex 0
while { [string index $format_model $beginindex] == "\n" } {
incr beginindex
}
set endindex $beginindex
while { [string is space [string index $format_model $endindex]] } {
incr endindex
}
set tabprefix [string range $pattern $beginindex $endindex-1]
set newformat ""
foreach line [split $format_model \n] {
if {[string trim $line] == ""} {
append newformat "\n"
continue
}
if {[string first $tabprefix $line] == 0} {
set line [string range $line [string length $tabprefix] end]
}
append newformat $line\n
set ie [string first {$} $line]
if {$ie != -1} {
if {[string range $line $ie end] == {$entries}} {
set ptabprefix "[string range $line 0 $ie-1]"
}
}
}
set format_model $newformat
unset newformat
}
set entries ""
if {[string trim $pattern] != "" } {
set prevval 0
set pattern [string trim $pattern]
# The first "$::model" will expand into variable names
# as defined there.
foreach [list {*}$::model] [no_comments $::loggers] {
if {$prevval + 1 != $id} {
append entries "\n"
}
append entries "${ptabprefix}[subst -nobackslashes $pattern]\n"
set prevval $id
}
}
if {$hpattern != ""} {
if {$hpattern == "="} {
set hpattern $pattern
} else {
set hpattern [string trim $hpattern]
}
# Extra line to separate from the normal entries
append entries "\n"
foreach [list {*}$::model] [no_comments $::hidden_loggers] {
append entries "${ptabprefix}[subst -nobackslashes $hpattern]\n"
}
}
if { [dict exists $::special $target] } {
set code [subst [dict get $::special $target]]
# The code should contain "append entries" !
eval $code
}
set entries [string trim $entries]
if {$format_model == ""} {
set format_model $entries
}
# For any case, cut external spaces
puts $od [string trim [subst -nocommands -nobackslashes $format_model]]
}
proc debug_vars {list} {
set output ""
foreach name $list {
upvar $name _${name}
lappend output "${name}=[set _${name}]"
}
return $output
}
# MAIN
set entryfiles $argv
if {$entryfiles == ""} {
set entryfiles [dict keys $generation]
} else {
foreach ef $entryfiles {
if { $ef ni [dict keys $generation] } {
error "Unknown generation target: $entryfiles"
}
}
}
foreach f $entryfiles {
# Set simple relative path, if the file isn't defined as path.
if { [llength [file split $f]] == 1 } {
set filepath $f
} else {
set filepath [file join $path $f]
}
puts stderr "Generating '$filepath'"
set od [open $filepath.tmp w]
generate_file $od $f
close $od
if { [file exists $filepath] } {
puts "WARNING: will overwrite exiting '$f'. Hit ENTER to confirm, or Control-C to stop"
gets stdin
}
file rename -force $filepath.tmp $filepath
}
puts stderr Done.

View file

@ -11,7 +11,7 @@ ExternalProject_Add(
BINARY_DIR "@GOOGLETEST_DOWNLOAD_ROOT@/googletest-build"
GIT_REPOSITORY
https://github.com/google/googletest.git
GIT_TAG release-1.8.1
GIT_TAG release-1.10.0
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""

View file

@ -12,11 +12,11 @@ include(CheckCXXSourceCompiles)
# Useful for combinging paths
function(adddirname prefix lst out_lst)
set(output)
foreach(item ${lst})
list(APPEND output "${prefix}/${item}")
endforeach()
set(${out_lst} ${${out_lst}} ${output} PARENT_SCOPE)
set(output)
foreach(item ${lst})
list(APPEND output "${prefix}/${item}")
endforeach()
set(${out_lst} ${${out_lst}} ${output} PARENT_SCOPE)
endfunction()
# Splits a version formed as "major.minor.patch" recorded in variable 'prefix'
@ -32,11 +32,11 @@ ENDMACRO(set_version_variables)
# Sets given variable to 1, if the condition that follows it is satisfied.
# Otherwise set it to 0.
MACRO(set_if varname)
IF(${ARGN})
SET(${varname} 1)
ELSE(${ARGN})
SET(${varname} 0)
ENDIF(${ARGN})
IF(${ARGN})
SET(${varname} 1)
ELSE(${ARGN})
SET(${varname} 0)
ENDIF(${ARGN})
ENDMACRO(set_if)
FUNCTION(join_arguments outvar)
@ -49,83 +49,8 @@ FUNCTION(join_arguments outvar)
set (${outvar} ${output} PARENT_SCOPE)
ENDFUNCTION()
# LEGACY. PLEASE DON'T USE ANYMORE.
MACRO(MafRead maffile)
message(WARNING "MafRead is deprecated. Please use MafReadDir instead")
# ARGN contains the extra "section-variable" pairs
# If empty, return nothing
set (MAFREAD_TAGS
SOURCES # source files
PUBLIC_HEADERS # installable headers for include
PROTECTED_HEADERS # installable headers used by other headers
PRIVATE_HEADERS # non-installable headers
)
cmake_parse_arguments(MAFREAD_VAR "" "${MAFREAD_TAGS}" "" ${ARGN})
# Arguments for these tags are variables to be filled
# with the contents of particular section.
# While reading the file, extract the section.
# Section is recognized by either first uppercase character or space.
# @c http://cmake.org/pipermail/cmake/2007-May/014222.html
FILE(READ ${maffile} MAFREAD_CONTENTS)
STRING(REGEX REPLACE ";" "\\\\;" MAFREAD_CONTENTS "${MAFREAD_CONTENTS}")
STRING(REGEX REPLACE "\n" ";" MAFREAD_CONTENTS "${MAFREAD_CONTENTS}")
#message("DEBUG: MAF FILE CONTENTS: ${MAFREAD_CONTENTS}")
#message("DEBUG: PASSED VARIABLES:")
#foreach(DEBUG_VAR ${MAFREAD_TAGS})
# message("DEBUG: ${DEBUG_VAR}=${MAFREAD_VAR_${DEBUG_VAR}}")
#endforeach()
# The unnamed section becomes SOURCES
set (MAFREAD_VARIABLE ${MAFREAD_VAR_SOURCES})
set (MAFREAD_UNASSIGNED "")
FOREACH(MAFREAD_LINE ${MAFREAD_CONTENTS})
# Test what this line is
string(STRIP ${MAFREAD_LINE} MAFREAD_OLINE)
string(SUBSTRING ${MAFREAD_OLINE} 0 1 MAFREAD_FIRST)
#message("DEBUG: LINE='${MAFREAD_LINE}' FIRST='${MAFREAD_FIRST}'")
# The 'continue' command is cmake 3.2 - very late discovery
if (MAFREAD_FIRST STREQUAL "")
#message("DEBUG: ... skipped: empty")
elseif (MAFREAD_FIRST STREQUAL "#")
#message("DEBUG: ... skipped: comment")
else()
# Will be skipped if the line was a comment/empty
string(REGEX MATCH "[ A-Z]" MAFREAD_SECMARK ${MAFREAD_FIRST})
if (MAFREAD_SECMARK STREQUAL "")
# This isn't a section, it's a list element.
#message("DEBUG: ITEM: ${MAFREAD_OLINE} --> ${MAFREAD_VARIABLE}")
LIST(APPEND ${MAFREAD_VARIABLE} ${MAFREAD_OLINE})
else()
# It's a section - change the running variable
# Make it section name
STRING(REPLACE " " "_" MAFREAD_SECNAME ${MAFREAD_OLINE})
set(MAFREAD_VARIABLE ${MAFREAD_VAR_${MAFREAD_SECNAME}})
if (MAFREAD_VARIABLE STREQUAL "")
set(MAFREAD_VARIABLE MAFREAD_UNASSIGNED)
endif()
#message("DEBUG: NEW SECTION: '${MAFREAD_SECNAME}' --> VARIABLE: '${MAFREAD_VARIABLE}'")
endif()
endif()
ENDFOREACH()
# Final debug report
#set (ALL_VARS "")
#message("DEBUG: extracted variables:")
#foreach(DEBUG_VAR ${MAFREAD_TAGS})
# list(APPEND ALL_VARS ${MAFREAD_VAR_${DEBUG_VAR}})
#endforeach()
#list(REMOVE_DUPLICATES ALL_VARS)
#foreach(DEBUG_VAR ${ALL_VARS})
# message("DEBUG: --> ${DEBUG_VAR} = ${${DEBUG_VAR}}")
#endforeach()
ENDMACRO(MafRead)
# New version of MafRead macro, which automatically adds directory
# prefix. This should also resolve each relative path.
# The directory specifies the location of maffile and
# all files specified in the list.
MACRO(MafReadDir directory maffile)
# ARGN contains the extra "section-variable" pairs
# If empty, return nothing
@ -155,11 +80,11 @@ MACRO(MafReadDir directory maffile)
configure_file(${directory}/${maffile} dummy_${maffile}.cmake.out)
file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/dummy_${maffile}.cmake.out)
#message("DEBUG: MAF FILE CONTENTS: ${MAFREAD_CONTENTS}")
#message("DEBUG: PASSED VARIABLES:")
#foreach(DEBUG_VAR ${MAFREAD_TAGS})
# message("DEBUG: ${DEBUG_VAR}=${MAFREAD_VAR_${DEBUG_VAR}}")
#endforeach()
#message("DEBUG: MAF FILE CONTENTS: ${MAFREAD_CONTENTS}")
#message("DEBUG: PASSED VARIABLES:")
#foreach(DEBUG_VAR ${MAFREAD_TAGS})
# message("DEBUG: ${DEBUG_VAR}=${MAFREAD_VAR_${DEBUG_VAR}}")
#endforeach()
# The unnamed section becomes SOURCES
set (MAFREAD_VARIABLE ${MAFREAD_VAR_SOURCES})
@ -188,11 +113,60 @@ MACRO(MafReadDir directory maffile)
if (${MAFREAD_SECTION_TYPE} STREQUAL file)
get_filename_component(MAFREAD_OLINE ${directory}/${MAFREAD_OLINE} ABSOLUTE)
endif()
LIST(APPEND ${MAFREAD_VARIABLE} ${MAFREAD_OLINE})
set (MAFREAD_CONDITION_OK 1)
if (DEFINED MAFREAD_CONDITION_LIST)
FOREACH(MFITEM IN ITEMS ${MAFREAD_CONDITION_LIST})
separate_arguments(MFITEM)
FOREACH(MFVAR IN ITEMS ${MFITEM})
STRING(SUBSTRING ${MFVAR} 0 1 MFPREFIX)
if (MFPREFIX STREQUAL "!")
STRING(SUBSTRING ${MFVAR} 1 -1 MFVAR)
if (${MFVAR})
set (MFCONDITION_RESULT 0)
else()
set (MFCONDITION_RESULT 1)
endif()
else()
if (${MFVAR})
set (MFCONDITION_RESULT 1)
else()
set (MFCONDITION_RESULT 0)
endif()
endif()
#message("CONDITION: ${MFPREFIX} ${MFVAR} -> ${MFCONDITION_RESULT}")
MATH(EXPR MAFREAD_CONDITION_OK "${MAFREAD_CONDITION_OK} & (${MFCONDITION_RESULT})")
ENDFOREACH()
ENDFOREACH()
endif()
if (MAFREAD_CONDITION_OK)
LIST(APPEND ${MAFREAD_VARIABLE} ${MAFREAD_OLINE})
else()
#message("... NOT ADDED ITEM: ${MAFREAD_OLINE}")
endif()
else()
# It's a section - change the running variable
# It's a section
# Check for conditionals (clear current conditions first)
unset(MAFREAD_CONDITION_LIST)
STRING(FIND ${MAFREAD_OLINE} " -" MAFREAD_HAVE_CONDITION)
if (NOT MAFREAD_HAVE_CONDITION EQUAL -1)
# Cut off conditional specification, and
# grab the section name and condition list
STRING(REPLACE " -" ";" MAFREAD_CONDITION_LIST ${MAFREAD_OLINE})
#message("CONDITION READ: ${MAFREAD_CONDITION_LIST}")
LIST(GET MAFREAD_CONDITION_LIST 0 MAFREAD_OLINE)
LIST(REMOVE_AT MAFREAD_CONDITION_LIST 0)
#message("EXTRACTING SECTION=${MAFREAD_OLINE} CONDITIONS=${MAFREAD_CONDITION_LIST}")
endif()
# change the running variable
# Make it section name
STRING(REPLACE " " "_" MAFREAD_SECNAME ${MAFREAD_OLINE})
#message("MAF SECTION: ${MAFREAD_SECNAME}")
# The cmake's version of 'if (MAFREAD_SECNAME[0] == '-')' - sigh...
string(SUBSTRING ${MAFREAD_SECNAME} 0 1 MAFREAD_SECNAME0)
@ -212,15 +186,15 @@ MACRO(MafReadDir directory maffile)
ENDFOREACH()
# Final debug report
#set (ALL_VARS "")
#message("DEBUG: extracted variables:")
#foreach(DEBUG_VAR ${MAFREAD_TAGS})
# list(APPEND ALL_VARS ${MAFREAD_VAR_${DEBUG_VAR}})
#endforeach()
#list(REMOVE_DUPLICATES ALL_VARS)
#foreach(DEBUG_VAR ${ALL_VARS})
# message("DEBUG: --> ${DEBUG_VAR} = ${${DEBUG_VAR}}")
#endforeach()
#set (ALL_VARS "")
#message("DEBUG: extracted variables:")
#foreach(DEBUG_VAR ${MAFREAD_TAGS})
# list(APPEND ALL_VARS ${MAFREAD_VAR_${DEBUG_VAR}})
#endforeach()
#list(REMOVE_DUPLICATES ALL_VARS)
#foreach(DEBUG_VAR ${ALL_VARS})
# message("DEBUG: --> ${DEBUG_VAR} = ${${DEBUG_VAR}}")
#endforeach()
ENDMACRO(MafReadDir)
# NOTE: This is historical only. Not in use.
@ -240,9 +214,9 @@ MACRO(GetMafHeaders directory outvar)
ENDMACRO(GetMafHeaders)
function (getVarsWith _prefix _varResult)
get_cmake_property(_vars VARIABLES)
string (REGEX MATCHALL "(^|;)${_prefix}[A-Za-z0-9_]*" _matchedVars "${_vars}")
set (${_varResult} ${_matchedVars} PARENT_SCOPE)
get_cmake_property(_vars VARIABLES)
string (REGEX MATCHALL "(^|;)${_prefix}[A-Za-z0-9_]*" _matchedVars "${_vars}")
set (${_varResult} ${_matchedVars} PARENT_SCOPE)
endfunction()
function (check_testcode_compiles testcode libraries _successful)
@ -254,15 +228,18 @@ function (check_testcode_compiles testcode libraries _successful)
set (CMAKE_REQUIRED_LIBRARIES ${save_required_libraries})
endfunction()
function (test_requires_clock_gettime _result)
function (test_requires_clock_gettime _enable _linklib)
# This function tests if clock_gettime can be used
# - at all
# - with or without librt
# Result will be:
# rt (if librt required)
# "" (if no extra libraries required)
# -- killed by FATAL_ERROR if clock_gettime is not available
# - CLOCK_MONOTONIC is available, link with librt:
# _enable = ON; _linklib = "-lrt".
# - CLOCK_MONOTONIC is available, link without librt:
# _enable = ON; _linklib = "".
# - CLOCK_MONOTONIC is not available:
# _enable = OFF; _linklib = "-".
set (code "
#include <time.h>
@ -275,17 +252,39 @@ function (test_requires_clock_gettime _result)
check_testcode_compiles(${code} "" HAVE_CLOCK_GETTIME_IN)
if (HAVE_CLOCK_GETTIME_IN)
message(STATUS "Checked clock_gettime(): no extra libs needed")
set (${_result} "" PARENT_SCOPE)
message(STATUS "CLOCK_MONOTONIC: available, no extra libs needed")
set (${_enable} ON PARENT_SCOPE)
set (${_linklib} "" PARENT_SCOPE)
return()
endif()
check_testcode_compiles(${code} "rt" HAVE_CLOCK_GETTIME_LIBRT)
if (HAVE_CLOCK_GETTIME_LIBRT)
message(STATUS "Checked clock_gettime(): requires -lrt")
set (${_result} "-lrt" PARENT_SCOPE)
message(STATUS "CLOCK_MONOTONIC: available, requires -lrt")
set (${_enable} ON PARENT_SCOPE)
set (${_linklib} "-lrt" PARENT_SCOPE)
return()
endif()
message(FATAL_ERROR "clock_gettime() is not available on this system")
set (${_enable} OFF PARENT_SCOPE)
set (${_linklib} "-" PARENT_SCOPE)
message(STATUS "CLOCK_MONOTONIC: not available on this system")
endfunction()
function (parse_compiler_type wct _type _suffix)
if (wct STREQUAL "")
set(${_type} "" PARENT_SCOPE)
set(${_suffix} "" PARENT_SCOPE)
else()
string(REPLACE "-" ";" OUTLIST ${wct})
list(LENGTH OUTLIST OUTLEN)
list(GET OUTLIST 0 ITEM)
set(${_type} ${ITEM} PARENT_SCOPE)
if (OUTLEN LESS 2)
set(_suffix "" PARENT_SCOPE)
else()
list(GET OUTLIST 1 ITEM)
set(${_suffix} "-${ITEM}" PARENT_SCOPE)
endif()
endif()
endfunction()

View file

@ -151,10 +151,10 @@ if (NOT DEFINED IOS_ARCH)
set (IOS_ARCH x86_64)
endif (${IOS_PLATFORM} STREQUAL OS)
endif(NOT DEFINED IOS_ARCH)
set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS")
set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE STRING "Build architecture for iOS")
# Set the find root to the iOS developer roots and to user defined paths
set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root")
set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE STRING "iOS find search path root")
# default to searching for frameworks first
set (CMAKE_FIND_FRAMEWORK FIRST)

View file

@ -0,0 +1,38 @@
"
" SRT - Secure, Reliable, Transport
" Copyright (c) 2020 Haivision Systems Inc.
"
" This Source Code Form is subject to the terms of the Mozilla Public
" License, v. 2.0. If a copy of the MPL was not distributed with this
" file, You can obtain one at http://mozilla.org/MPL/2.0/.
"
" This file describes MAF ("manifest") file syntax used by
" SRT project.
"
if exists("b:current_syntax")
finish
endif
" conditionals
syn match mafCondition contained " - [!A-Za-z].*"hs=s+2
" section
syn match mafSection "^[A-Z][0-9A-Za-z_].*$" contains=mafCondition
syn match mafsection "^ .*$" contains=mafCondition
" comments
syn match mafComment "^\s*\zs#.*$"
syn match mafComment "\s\zs#.*$"
syn match mafComment contained "#.*$"
" hilites
hi def link mafComment Comment
hi def link mafSection Statement
hi def link mafCondition Number
let b:current_syntax = "maf"

View file

@ -0,0 +1,27 @@
# Script Description
Script designed to generate release notes template with main sections, contributors list, and detailed changelog out of `.csv` SRT git log file. The output `release-notes.md` file is generated in the root folder.
In order to obtain the git log file since the previous release (e.g., v1.4.0), use the following command:
```shell
git log --pretty=format:"%h|%s|%an|%ae" v1.4.0...HEAD > commits.csv
```
Use the produced `commits.csv` file as an input to the script:
```shell
python scripts/release-notes/generate-release-notes.py commits.csv
```
The script produces `release-notes.md` as an output.
## Requirements
* Python 3.6+
To install Python libraries use:
```shell
pip install -r requirements.txt
```

View file

@ -0,0 +1,120 @@
import enum
import click
import numpy as np
import pandas as pd
@enum.unique
class Area(enum.Enum):
core = 'core'
tests = 'tests'
build = 'build'
apps = 'apps'
docs = 'docs'
def define_area(msg):
areas = [e.value for e in Area]
for area in areas:
if msg.startswith(f'[{area}] '):
return area
return np.NaN
def delete_prefix(msg):
prefixes = [f'[{e.value}] ' for e in Area]
for prefix in prefixes:
if msg.startswith(prefix):
return msg[len(prefix):]
return msg[:]
def write_into_changelog(df, f):
f.write('\n')
for _, row in df.iterrows():
f.write(f"\n{row['commit']} {row['message']}")
f.write('\n')
@click.command()
@click.argument(
'git_log',
type=click.Path(exists=True)
)
def main(git_log):
"""
Script designed to generate release notes template with main sections,
contributors list, and detailed changelog out of .csv SRT git log file.
"""
df = pd.read_csv(git_log, sep = '|', names = ['commit', 'message', 'author', 'email'])
df['area'] = df['message'].apply(define_area)
df['message'] = df['message'].apply(delete_prefix)
# Split commits by areas
core = df[df['area']==Area.core.value]
tests = df[df['area']==Area.tests.value]
build = df[df['area']==Area.build.value]
apps = df[df['area']==Area.apps.value]
docs = df[df['area']==Area.docs.value]
other = df[df['area'].isna()]
# Define individual contributors
contributors = df.groupby(['author', 'email'])
contributors = list(contributors.groups.keys())
with open('release-notes.md', 'w') as f:
f.write('# Release Notes\n')
f.write('\n## API / ABI / Integration Changes\n')
f.write('\n**API/ABI version: 1.x.**\n')
f.write('\n## New Features and Improvements\n')
f.write('\n## Important Bug Fixes\n')
f.write('\n## Build\n')
f.write('\n## Documentation\n')
f.write('\n## Contributors\n')
for name, email in contributors:
f.write(f'\n{name} <{email}>')
f.write('\n')
f.write('\n## Changelog\n')
f.write('\n<details><summary>Click to expand/collapse</summary>')
f.write('\n<p>')
f.write('\n')
if not core.empty:
f.write('\n### Core Functionality')
write_into_changelog(core, f)
if not tests.empty:
f.write('\n### Unit Tests')
write_into_changelog(tests, f)
if not build.empty:
f.write('\n### Build Scripts (CMake, etc.)')
write_into_changelog(build, f)
if not apps.empty:
f.write('\n### Sample Applications')
write_into_changelog(apps, f)
if not docs.empty:
f.write('\n### Documentation')
write_into_changelog(docs, f)
if not other.empty:
f.write('\n### Other')
write_into_changelog(other, f)
f.write('\n</p>')
f.write('\n</details>')
if __name__ == '__main__':
main()

View file

@ -0,0 +1,3 @@
click>=7.1.2
numpy>=1.19.1
pandas>=0.25.3

View file

@ -27,13 +27,22 @@ if($Env:APPVEYOR){
Update-AppveyorBuild -Version "$majorVer.$minorVer.$patchVer.$buildNum"
$FileDescriptionBranchCommitValue = "$Env:APPVEYOR_REPO_NAME - $($Env:APPVEYOR_REPO_BRANCH) ($($Env:APPVEYOR_REPO_COMMIT.substring(0,8)))"
}
if($Env:TEAMCITY_VERSION){
#make TeamCity update with this new version number
Write-Output "##teamcity[buildNumber '$majorVer.$minorVer.$patchVer.$buildNum']"
Write-Output "##teamcity[setParameter name='MajorVersion' value='$majorVer']"
Write-Output "##teamcity[setParameter name='MinorVersion' value='$minorVer']"
Write-Output "##teamcity[setParameter name='PatchVersion' value='$patchVer']"
Write-Output "##teamcity[setParameter name='BuildVersion' value='$buildNum']"
$FileDescriptionBranchCommitValue = "$majorVer.$minorVer.$patchVer.$buildNum - ($($Env:BUILD_VCS_NUMBER.substring(0,8)))"
}
#find C++ resource files and update file description with branch / commit details
$FileDescriptionStringRegex = '(\bVALUE\s+\"FileDescription\"\s*\,\s*\")([^\"]*\\\")*[^\"]*(\")'
Get-ChildItem -Path "./srtcore/srt_shared.rc" | ForEach-Object {
Get-ChildItem -Path "../srtcore/srt_shared.rc" | ForEach-Object {
$fileName = $_
Write-Host "Processing metadata changes for file: $fileName"
Write-Output "Processing metadata changes for file: $fileName"
$FileLines = Get-Content -path $fileName

View file

@ -0,0 +1,938 @@
-- @brief srt-dev Protocol dissector plugin
-- create a new dissector
local NAME = "SRT-dev"
local srt_dev = Proto(NAME, "SRT-dev Protocol")
-- create a preference of a Protocol
srt_dev.prefs["srt_udp_port"] = Pref.uint("SRT UDP Port", 1935, "SRT UDP Port")
-- create fields of srt_dev
-- Base.HEX, Base.DEC, Base.OCT, Base.UNIT_STRING, Base.NONE
local fields = srt_dev.fields
-- General field
local pack_type_select = {
[0] = "Data Packet",
[1] = "Control Packet"
}
fields.pack_type_tree = ProtoField.uint32(NAME .. ".pack_type_tree", "Packet Type", base.HEX)
fields.pack_type = ProtoField.uint16("srt_dev.pack_type", "Packet Type", base.HEX, pack_type_select, 0x8000)
fields.reserve = ProtoField.uint16("srt_dev.reserve", "Reserve", base.DEC)
fields.additional_info = ProtoField.uint32("srt_dev.additional_info", "Additional Information", base.DEC)
fields.time_stamp = ProtoField.uint32("srt_dev.time_stamp", "Time Stamp", base.DEC)
fields.dst_sock = ProtoField.uint32("srt_dev.dst_sock", "Destination Socket ID", base.DEC)
fields.none = ProtoField.none("srt_dev.none", "none", base.NONE)
-- Data packet fields
fields.data_flag_info_tree = ProtoField.uint8("srt_dev.data_flag_info_tree", "Data Flag Info", base.HEX)
local FF_state_select = {
[0] = "[Middle packet]",
[1] = "[Last packet]",
[2] = "[First packet]",
[3] = "[Single packet]"
}
fields.FF_state = ProtoField.uint8("srt_dev.FF_state", "FF state", base.HEX, FF_state_select, 0xC0)
local O_state_select = {
[0] = "[ORD_RELAX]",
[1] = "[ORD_REQUIRED]"
}
fields.O_state = ProtoField.uint8("srt_dev.O_state", "O state", base.HEX, O_state_select, 0x20)
local KK_state_select = {
[0] = "[Not encrypted]",
[1] = "[Data encrypted with even key]",
[2] = "[Data encrypted with odd key]"
}
fields.KK_state = ProtoField.uint8("srt_dev.KK_state", "KK state", base.HEX, KK_state_select, 0x18)
local R_state_select = {
[0] = "[ORIGINAL]",
[1] = "[RETRANSMITTED]"
}
fields.R_state = ProtoField.uint8("srt_dev.R_state", "R state", base.HEX, R_state_select, 0x04)
fields.seq_num = ProtoField.uint32("srt_dev.seq_num", "Sequence Number", base.DEC)
fields.msg_num = ProtoField.uint32("srt_dev.msg_num", "Message Number", base.DEC)--, nil, 0x3FFFFFF)
-- control packet fields
local msg_type_select = {
[0] = "[HANDSHAKE]",
[1] = "[KEEPALIVE]",
[2] = "[ACK]",
[3] = "[NAK(Loss Report)]",
[4] = "[Congestion Warning]",
[5] = "[Shutdown]",
[6] = "[ACKACK]",
[7] = "[Drop Request]",
[8] = "[Peer Error]",
[0x7FFF] = "[Message Extension Type]"
}
fields.msg_type = ProtoField.uint16("srt_dev.msg_type", "Message Type", base.HEX, msg_type_select, 0x7FFF)
fields.msg_ext_type = ProtoField.uint16("srt_dev.msg_ext_type", "Message Extented Type", base.DEC)
local flag_state_select = {
[0] = "Unset",
[1] = "Set"
}
-- Handshake packet fields
fields.UDT_version = ProtoField.uint32("srt_dev.UDT_version", "UDT Version", base.DEC)
fields.sock_type = ProtoField.uint32("srt_dev.sock_type", "Socket Type", base.DEC)
fields.ency_fld = ProtoField.uint16("srt_dev.ency_fld", "Encryption Field", base.DEC)
fields.ext_fld = ProtoField.uint16("srt_dev.ext_fld", "Extension Fields", base.HEX)
fields.ext_fld_tree = ProtoField.uint16("srt_dev.ext_fld_tree", "Extension Fields Tree", base.HEX)
fields.hsreq = ProtoField.uint16("srt_dev.hsreq", "HS_EXT_HSREQ", base.HEX, flag_state_select, 0x1)
fields.kmreq = ProtoField.uint16("srt_dev.kmreq", "HS_EXT_KMREQ", base.HEX, flag_state_select, 0x2)
fields.config = ProtoField.uint16("srt_dev.config", "HS_EXT_CONFIG", base.HEX, flag_state_select, 0x4)
fields.isn = ProtoField.uint32("srt_dev.isn", "Initial packet sequence number", base.DEC)
fields.mss = ProtoField.uint32("srt_dev.mss", "Max Packet Size", base.DEC)
fields.fc = ProtoField.uint32("srt_dev.fc", "Maximum Flow Window Size", base.DEC)
fields.conn_type = ProtoField.int32("srt_dev.conn_type", "Connection Type", base.DEC)
fields.sock_id = ProtoField.uint32("srt_dev.sock_id", "Socket ID", base.DEC)
fields.syn_cookie = ProtoField.uint32("srt_dev.syn_cookie", "SYN cookie", base.DEC)
fields.peer_ipaddr = ProtoField.none("srt_dev.peer_ipaddr", "Peer IP address", base.NONE)
fields.peer_ipaddr_4 = ProtoField.ipv4("srt_dev.peer_ipaddr", "Peer IP address")
fields.peer_ipaddr_6 = ProtoField.ipv6("srt_dev.peer_ipaddr", "Peer IP address")
local ext_type_select = {
[-1] = "SRT_CMD_NONE",
[0] = "SRT_CMD_REJECT",
[1] = "SRT_CMD_HSREQ",
[2] = "SRT_CMD_HSRSP",
[3] = "SRT_CMD_KMREQ",
[4] = "SRT_CMD_KMRSP",
[5] = "SRT_CMD_SID",
[6] = "SRT_CMD_CONGESTION",
[7] = "SRT_CMD_FILTER",
[8] = "SRT_CMD_GROUP"
}
fields.ext_type_msg_tree = ProtoField.none("srt_dev.ext_type", "Extension Type Message", base.NONE)
fields.ext_type = ProtoField.uint16("srt_dev.ext_type", "Extension Type", base.HEX, ext_type_select, 0xF)
fields.ext_size = ProtoField.uint16("srt_dev.ext_size", "Extension Size", base.DEC)
-- Handshake packet, ext type == SRT_CMD_HSREQ or SRT_CMD_HSRSP field
fields.srt_version = ProtoField.uint32("srt_dev.srt_version", "SRT Version", base.HEX)
fields.srt_flags = ProtoField.uint32("srt_dev.srt_flags", "SRT Flags", base.HEX)
fields.tsbpb_resv = ProtoField.uint16("srt_dev.tsbpb_resv", "TsbPb Receive", base.DEC)
fields.tsbpb_delay = ProtoField.uint16("srt_dev.tsbpb_delay", "TsbPb Delay", base.DEC)
fields.tsbpd_delay = ProtoField.uint16("srt_dev.tsbpd_delay", "TsbPd Delay", base.DEC)
fields.rcv_tsbpd_delay = ProtoField.uint16("srt_dev.rcv_tsbpd_delay", "Receiver TsbPd Delay", base.DEC)
fields.snd_tsbpd_delay = ProtoField.uint16("srt_dev.snd_tsbpd_delay", "Sender TsbPd Delay", base.DEC)
-- V and PT status flag
local V_state_select = {
[1] = "Initial version"
}
fields.V_state = ProtoField.uint8("srt_dev.V_state", "V", base.HEX, V_state_select, 0x70)
local PT_state_select = {
[0] = "Reserved",
[1] = "MSmsg",
[2] = "KMmsg",
[7] = "Reserved to discriminate MPEG-TS packet(0x47=sync byte)"
}
fields.PT_state = ProtoField.uint8("srt_dev.PT_state", "PT", base.HEX, state_table, 0xF)
fields.sign = ProtoField.uint16("srt_dev.sign", "Signature", base.HEX)
local resv_select = {
[0] = "Reserved for flag extension or other usage"
}
fields.resv = ProtoField.uint8("srt_dev.resv", "Resv", base.DEC, state_table, 0xFC)
fields.ext_KK_state = ProtoField.uint8("srt_dev.ext_KK_state", "KK_state", base.HEX, KK_state_select, 0x3)
fields.KEKI = ProtoField.uint32("srt_dev.KEKI", "KEKI", base.DEC)
fields.cipher = ProtoField.uint8("srt_dev.cipher", "Cipher", base.DEC)
fields.auth = ProtoField.uint8("srt_dev.auth", "auth", base.DEC)
fields.SE = ProtoField.uint8("srt_dev.SE", "SE", base.DEC)
fields.resv1 = ProtoField.uint8("srt_dev.resv1", "resv1", base.DEC)
fields.resv2 = ProtoField.uint16("srt_dev.resv2", "resv2", base.DEC)
fields.slen = ProtoField.uint8("srt_dev.slen", "Salt length(bytes)/4", base.DEC)
fields.klen = ProtoField.uint8("srt_dev.klen", "SEK length(bytes)/4", base.DEC)
fields.salt = ProtoField.uint32("srt_dev.salt", "Salt key", base.DEC)
fields.wrap = ProtoField.none("srt_dev.wrap", "Wrap key(s)", base.NONE)
-- Wrap Field
fields.ICV = ProtoField.uint64("srt_dev.ICV", "Integerity Check Vector", base.HEX)
fields.odd_key = ProtoField.stringz("srt_dev.odd_key", "Odd key", base.ASCII)
fields.even_key = ProtoField.stringz("srt_dev.even_key", "Even key", base.ASCII)
-- ext_type == SRT_CMD_SID field
fields.sid = ProtoField.string("srt_dev.sid", "Stream ID", base.ASCII)
-- ext_type == SRT_CMD_CONGESTION field
fields.congestion = ProtoField.string("srt_dev.congestion", "Congestion Controller", base.ASCII)
-- ext_type == SRT_CMD_FILTER field
fields.filter = ProtoField.string("srt_dev.filter", "Filter", base.ASCII)
-- ext_type == SRT_CMD_GROUP field
fields.group = ProtoField.string("srt_dev.group", "Group Data", base.ASCII)
-- SRT flags
fields.srt_opt_tsbpdsnd = ProtoField.uint32("srt_dev.srt_opt_tsbpdsnd", "SRT_OPT_TSBPDSND", base.HEX, flag_state_select, 0x1)
fields.srt_opt_tsbpdrcv = ProtoField.uint32("srt_dev.srt_opt_tsbpdrcv", "SRT_OPT_TSBPDRCV", base.HEX, flag_state_select, 0x2)
fields.srt_opt_haicrypt = ProtoField.uint32("srt_dev.srt_opt_haicrypt", "SRT_OPT_HAICRYPT", base.HEX, flag_state_select, 0x4)
fields.srt_opt_tlpktdrop = ProtoField.uint32("srt_dev.srt_opt_tlpktdrop", "SRT_OPT_TLPKTDROP", base.HEX, flag_state_select, 0x8)
fields.srt_opt_nakreport = ProtoField.uint32("srt_dev.srt_opt_nakreport", "SRT_OPT_NAKREPORT", base.HEX, flag_state_select, 0x10)
fields.srt_opt_rexmitflg = ProtoField.uint32("srt_dev.srt_opt_rexmitflg", "SRT_OPT_REXMITFLG", base.HEX, flag_state_select, 0x20)
fields.srt_opt_stream = ProtoField.uint32("srt_dev.srt_opt_stream", "SRT_OPT_STREAM", base.HEX, flag_state_select, 0x40)
-- ACK fields
fields.last_ack_pack = ProtoField.uint32("srt_dev.last_ack_pack", "Last ACK Packet Sequence Number", base.DEC)
fields.rtt = ProtoField.int32("srt_dev.rtt", "Round Trip Time", base.DEC)
fields.rtt_variance = ProtoField.int32("srt_dev.rtt_variance", "Round Trip Time Variance", base.DEC)
fields.buf_size = ProtoField.uint32("srt_dev.buf_size", "Available Buffer Size", base.DEC)
fields.pack_rcv_rate = ProtoField.uint32("srt_dev.pack_rcv_rate", "Packet Receiving Rate", base.DEC)
fields.est_link_capacity = ProtoField.uint32("srt_dev.est_link_capacity", "Estimated Link Capacity", base.DEC)
fields.rcv_rate = ProtoField.uint32("srt_dev.rcv_rate", "Receiving Rate", base.DEC)
-- ACKACK fields
fields.ack_num = ProtoField.uint32("srt_dev.ack_num", "ACK number", base.DEC)
fields.ctl_info = ProtoField.uint32("srt_dev.ctl_info", "Control Information", base.DEC)
-- KMRSP fields
local srt_km_state_select = {
[0] = "[SRT_KM_UNSECURED]",
[1] = "[SRT_KM_SECURING]",
[2] = "[SRT_KM_SECURED]",
[3] = "[SRT_KM_NOSECRET]",
[4] = "[SRT_KM_BADSECRET]"
}
fields.km_err = ProtoField.uint32("srt_dev.km_err", "Key Message Error", base.HEX, srt_km_state_select, 0xF)
-- NAK Control Packet fields
fields.lost_list_tree = ProtoField.none("srt_dev.lost_list_tree", "Lost Packet List", base.NONE)
fields.lost_pack_seq = ProtoField.uint32("srt_dev.lost_pack_seq", "Lost Packet Sequence Number", base.DEC)
fields.lost_pack_range_tree = ProtoField.none("srt_dev.lost_pack_range_tree", "Lost Packet Range", base.NONE)
fields.lost_start = ProtoField.uint32("srt_dev.lost_start", "Lost Starting Sequence", base.DEC)
fields.lost_up_to = ProtoField.uint32("srt_dev.lost_up_to", "Lost Up To(including)", base.DEC)
-- Dissect packet
function srt_dev.dissector (tvb, pinfo, tree)
-- Packet is based on UDP, so the data can be processed directly after UDP
local subtree = tree:add(srt_dev, tvb())
local offset = 0
-- Changes the protocol name
pinfo.cols.protocol = srt_dev.name
-- Take out the first bit of package
-- 0 -> Data Packet
-- 1 -> Control Packet
local typebit = bit.rshift(tvb(offset, 1):uint(), 7)
pack_type_tree = subtree:add(fields.pack_type_tree, tvb(offset, 4))
if typebit == 1 then
-- Handle Control Packet
pack_type_tree:add(fields.pack_type, tvb(offset, 2))
local msg_type = tvb(offset, 2):uint()
if msg_type ~= 0xFFFF then
-- If type field isn't '0x7FFF',it means packet is normal data packet, then handle type field
msg_type = bit.band(msg_type, 0x7FFF)
function parse_three_param()
-- Ignore Additional Info (this field is not defined in this packet type)
subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]")
offset = offset + 4
-- Handle Time Stamp
subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs")
offset = offset + 4
-- Handle Destination Socket
subtree:add(fields.dst_sock, tvb(offset, 4))
offset = offset + 4
end
local switch = {
[0] = function()
pinfo.cols.info:append(" [HANDSHAKE]")
pack_type_tree:append_text(" [HANDSHAKE]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2))
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
-- Handle Additional Info, Timestamp and Destination Socket
parse_three_param()
-- Handle UDT version field
local UDT_version = tvb(offset, 4):uint()
subtree:add(fields.UDT_version, tvb(offset, 4))
offset = offset + 4
if UDT_version == 4 then
-- UDT version is 4, packet is different from UDT version 5
-- Handle sock type
local sock_type = tvb(offset, 4):uint()
if sock_type == 1 then
subtree:add(fields.sock_type, tvb(offset, 4)):append_text(" [SRT_STREAM]")
elseif sock_type == 2 then
subtree:add(fields.sock_type, tvb(offset, 4)):append_text(" [SRT_DRAGAM]")
end
offset = offset + 4
elseif UDT_version == 5 then
-- Handle Encryption Field
local encr_fld = tvb(offset, 2):int()
if encr_fld == 0 then
subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (PBKEYLEN not advertised)")
elseif encr_fld == 2 then
subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-128)")
elseif encr_fld == 3 then
subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-192)")
else
subtree:add(fields.ency_fld, tvb(offset, 2)):append_text(" (AES-256)")
end
offset = offset + 2
-- Handle Extension Field
local ext_fld = tvb(offset, 2):int()
if ext_fld == 0x4A17 then
subtree:add(fields.ext_fld, tvb(offset, 2)):append_text(" [HSv5 MAGIC]")
else
-- Extension Field is HS_EXT_prefix
-- The define is in fiel handshake.h
local ext_fld_tree = subtree:add(fields.ext_fld_tree, tvb(offset, 2))
local str_table = { " [" }
ext_fld_tree:add(fields.hsreq, tvb(offset, 2))
if bit.band(tvb(offset, 2):uint(), 0x1) == 1 then
table.insert(str_table, "HS_EXT_HSREQ")
table.insert(str_table, " | ")
end
ext_fld_tree:add(fields.kmreq, tvb(offset, 2)):append_text(" [HS_EXT_KMREQ]")
if bit.band(tvb(offset, 2):uint(), 0x2) == 2 then
table.insert(str_table, "HS_EXT_KMREQ")
table.insert(str_table, " | ")
end
ext_fld_tree:add(fields.config, tvb(offset, 2)):append_text(" [HS_EXT_CONFIG]")
if bit.band(tvb(offset, 2):uint(), 0x4) == 4 then
table.insert(str_table, "HS_EXT_CONFIG")
table.insert(str_table, " | ")
end
table.remove(str_table)
table.insert(str_table, "]")
if ext_fld ~= 0 then
ext_fld_tree:append_text(table.concat(str_table))
end
end
offset = offset + 2
end
-- Handle Initial packet sequence number
subtree:add(fields.isn, tvb(offset, 4))
offset = offset + 4
-- Handle Maximum Packet Size
subtree:add(fields.mss, tvb(offset, 4))
offset = offset + 4
-- Handle Maximum Flow Window Size
subtree:add(fields.fc, tvb(offset, 4))
offset = offset + 4
-- Handle Connection Type
local conn_type = tvb(offset, 4):int()
local conn_type_tree = subtree:add(fields.conn_type, tvb(offset, 4))
if conn_type == 0 then
conn_type_tree:append_text(" [WAVEAHAND] (Rendezvous Mode)")
pinfo.cols.info:append(" [WAVEAHAND] (Rendezvous Mode)")
elseif conn_type == 1 then
conn_type_tree:append_text(" [INDUCTION]")
elseif conn_type == -1 then
conn_type_tree:append_text(" [CONCLUSION]")
elseif conn_type == -2 then
conn_type_tree:append_text(" [AGREEMENT] (Rendezvous Mode)")
pinfo.cols.info:append(" [AGREEMENT] (Rendezvous Mode)")
end
offset = offset + 4
-- Handle Socket ID
subtree:add(fields.sock_id, tvb(offset, 4))
offset = offset + 4
-- Handle SYN cookie
local syn_cookie = tvb(offset, 4):int()
subtree:add(fields.syn_cookie, tvb(offset, 4))
if syn_cookie == 0 then
conn_type_tree:append_text(" (Caller to Listener)")
pinfo.cols.info:append(" (Caller to Listener)")
else
if conn_type == 1 then
-- reports cookie from listener
conn_type_tree:append_text(" (Listener to Caller)")
pinfo.cols.info:append(" (Listener to Caller)")
end
end
offset = offset + 4
-- Handle Peer IP address
-- Note the network byte order
local the_last_96_bits = 0
the_last_96_bits = the_last_96_bits + math.floor(tvb(offset + 4, 4):int() * (2 ^ 16))
the_last_96_bits = the_last_96_bits + math.floor(tvb(offset + 8, 4):int() * (2 ^ 8))
the_last_96_bits = the_last_96_bits + tvb(offset + 12, 4):int()
if the_last_96_bits == 0 then
subtree:add_le(fields.peer_ipaddr_4, tvb(offset, 4))
else
subtree:add_le(fields.peer_ipaddr, tvb(offset, 16))
end
offset = offset + 16
-- UDT version is 4, packet handle finish
if UDT_version == 4 or offset == tvb:len() then
return
end
function process_ext_type()
-- Handle Ext Type, processing by type
local ext_type = tvb(offset, 2):int()
if ext_type == 1 or ext_type == 2 then
local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, 16))
if ext_type == 1 then
ext_type_msg_tree:append_text(" [SRT_CMD_HSREQ]")
ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
conn_type_tree:append_text(" (Caller to Listener)")
pinfo.cols.info:append(" (Caller to Listener)")
else
ext_type_msg_tree:append_text(" [SRT_CMD_HSRSP]")
ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
conn_type_tree:append_text(" (Listener to Caller)")
pinfo.cols.info:append(" (Listener to Caller)")
end
offset = offset + 2
-- Handle Ext Size
ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2))
offset = offset + 2
-- Handle SRT Version
ext_type_msg_tree:add(fields.srt_version, tvb(offset, 4))
offset = offset + 4
-- Handle SRT Flags
local SRT_flags_tree = ext_type_msg_tree:add(fields.srt_flags, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_tsbpdsnd, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_tsbpdrcv, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_haicrypt, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_tlpktdrop, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_nakreport, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_rexmitflg, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_stream, tvb(offset, 4))
offset = offset + 4
-- Handle Recv TsbPd Delay and Snd TsbPd Delay
if UDT_version == 4 then
ext_type_msg_tree:add(fields.tsbpd_delay, tvb(offset, 2)):append_text(" [Unused in HSv4]")
offset = offset + 2
ext_type_msg_tree:add(fields.tsbpb_delay, tvb(offset, 2))
offset = offset + 2
else
ext_type_msg_tree:add(fields.rcv_tsbpd_delay, tvb(offset, 2))
offset = offset + 2
ext_type_msg_tree:add(fields.snd_tsbpd_delay, tvb(offset, 2))
offset = offset + 2
end
elseif ext_type == 3 or ext_type == 4 then
local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, 16))
if ext_type == 3 then
ext_type_msg_tree:append_text(" [SRT_CMD_KMREQ]")
ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
conn_type_tree:append_text(" (Listener to Caller)")
else
ext_type_msg_tree:append_text(" [SRT_CMD_KMRSP]")
ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
end
offset = offset + 2
-- Handle Ext Size
local km_len = tvb(offset, 2):uint()
ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2)):append_text(" (byte/4)")
offset = offset + 2
-- Handle SRT_CMD_KMREQ message
-- V and PT status flag
ext_type_msg_tree:add(fields.V_state, tvb(offset, 1))
ext_type_msg_tree:add(fields.PT_state, tvb(offset, 1))
offset = offset + 1
-- Handle sign
ext_type_msg_tree:add(fields.sign, tvb(offset, 2)):append_text(" (/'HAI/' PnP Vendor ID in big endian order)")
offset = offset + 2
-- Handle resv
ext_type_msg_tree:add(fields.resv, tvb(offset, 1))
-- Handle KK flag
local KK = tvb(offset, 1):uint()
ext_type_msg_tree:add(fields.ext_KK_state, tvb(offset, 1))
offset = offset + 1
-- Handle KEKI
if tvb(offset, 4):uint() == 0 then
ext_type_msg_tree:add(fields.KEKI, tvb(offset, 4)):append_text(" (Default stream associated key(stream/system default))")
else
ext_type_msg_tree:add(fields.KEKI, tvb(offset, 4)):append_text(" (Reserved for manually indexed keys)")
end
offset = offset + 4
-- Handle Cipher
local cipher_node = ext_type_msg_tree:add(fields.cipher, tvb(offset, 1))
local cipher = tvb(offset, 1):uint()
if cipher == 0 then
elseif cipher == 1 then
cipher_node:append_text(" (AES-ECB(potentially for VF 2.0 compatible message))")
elseif cipher == 2 then
cipher_node:append_text(" (AES-CTR[FP800-38A])")
else
cipher_node:append_text(" (AES-CCM or AES-GCM)")
end
offset = offset + 1
-- Handle Auth
if tvb(offset, 1):uint() == 0 then
ext_type_msg_tree:add(fields.auth, tvb(offset, 1)):append_text(" (None or KEKI indexed crypto context)")
else
ext_type_msg_tree:add(fields.auth, tvb(offset, 1))
end
offset = offset + 1
-- Handle SE
local SE_node = ext_type_msg_tree:add(fields.SE, tvb(offset, 1))
local SE = tvb(offset, 1):uint()
if SE == 0 then
SE_node:append_text( " (Unspecified or KEKI indexed crypto context)")
elseif SE == 1 then
SE_node:append_text( " (MPEG-TS/UDP)")
elseif SE == 2 then
SE_node:append_text( " (MPEG-TS/SRT)")
end
offset = offset + 1
-- Handle resv1
ext_type_msg_tree:add(fields.resv1, tvb(offset, 1))
offset = offset + 1
-- Handle resv2
ext_type_msg_tree:add(fields.resv2, tvb(offset, 2))
offset = offset + 2
-- Handle slen
ext_type_msg_tree:add(fields.slen, tvb(offset, 1))
offset = offset + 1
-- Handle klen
local klen = tvb(offset, 1):uint()
ext_type_msg_tree:add(fields.klen, tvb(offset, 1))
offset = offset + 1
-- Handle salt key
ext_type_msg_tree:add(fields.salt, tvb(offset, slen * 4))
offset = offset + slen * 4
-- Handle wrap
-- Handle ICV
local wrap_len = 8 + KK * klen
local wrap_tree = ext_type_msg_tree:add(fields.wrap, tvb(offset, wrap_len))
wrap_tree:add(fields.ICV, tvb(offset, 8))
offset = offset + 8
-- If KK == 2, first key is Even key
if KK == 2 then
wrap_tree:add(fields.even_key, tvb(offset, klen))
offset = offset + klen;
end
-- Handle Odd key
wrap_tree:add(fields.odd_key, tvb(offset, klen))
offset = offset + klen;
elseif ext_type >= 5 and ext_type <= 8 then
local value_size = tvb(offset + 2, 2):uint() * 4
local ext_msg_size = 2 + 2 + value_size
local type_array = { " [SRT_CMD_SID]", " [SRT_CMD_CONGESTION]", " [SRT_CMD_FILTER]", " [SRT_CMD_GROUP]" }
local field_array = { fields.sid, fields.congestion, fields.filter, fields.group }
local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, ext_msg_size)):append_text(type_array[ext_type - 4])
ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
offset = offset + 2
-- Handle Ext Msg Value Size
ext_type_msg_tree:add(fields.ext_size, tvb(offset, 2)):append_text(" (byte/4)")
offset = offset + 2
-- Value
local value_table = {}
for pos = 0, value_size - 4, 4 do
table.insert(value_table, string.char(tvb(offset + pos + 3, 1):uint()))
table.insert(value_table, string.char(tvb(offset + pos + 2, 1):uint()))
table.insert(value_table, string.char(tvb(offset + pos + 1, 1):uint()))
table.insert(value_table, string.char(tvb(offset + pos, 1):uint()))
end
local value = table.concat(value_table)
ext_type_msg_tree:add(field_array[ext_type - 4], tvb(offset, value_size), value)
offset = offset + value_size
elseif ext_type == -1 then
local ext_type_msg_tree = subtree:add(fields.ext_type_msg_tree, tvb(offset, tvb:len() - offset)):append_text(" [SRT_CMD_NONE]")
ext_type_msg_tree:add(fields.ext_type, tvb(offset, 2))
offset = offset + 2
-- none
if offset == tvb:len() then
return
end
ext_type_msg_tree:add(fields.none, tvb(offset, tvb:len() - offset))
offset = tvb:len()
end
if offset == tvb:len() then
return
else
process_ext_type()
end
end
process_ext_type()
end,
[1] = function()
pinfo.cols.info:append(" [KEEPALIVE]")
pack_type_tree:append_text(" [KEEPALIVE]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [KEEPALIVE]")
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
-- Handle Additional Info, Time Stamp and Destination Socket
parse_three_param()
end,
[2] = function()
pinfo.cols.info:append(" [ACK]")
pack_type_tree:append_text(" [ACK]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2))
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
-- Handle ACK Number
subtree:add(fields.ack_num, tvb(offset, 4))
offset = offset + 4
-- Handle Time Stamp
subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs")
offset = offset + 4
-- Handle Destination Socket
subtree:add(fields.dst_sock, tvb(offset, 4))
offset = offset + 4
-- Handle Last Ack Packet Sequence
local last_ack_pack = tvb(offset, 4):uint()
pinfo.cols.info:append(" (Last ACK Seq:" .. last_ack_pack .. ")")
subtree:add(fields.last_ack_pack, tvb(offset, 4))
offset = offset + 4
-- Handle RTT
local rtt = tvb(offset, 4):int()
subtree:add(fields.rtt, tvb(offset, 4)):append_text(" μs")
offset = offset + 4
-- Handle RTT variance
if rtt < 0 then
subtree:add(fields.rtt_variance, tvb(offset, 4), -tvb(offset, 4):int())
else
subtree:add(fields.rtt_variance, tvb(offset, 4))
end
offset = offset + 4
-- Handle Available Buffer Size(pkts)
subtree:add(fields.buf_size, tvb(offset, 4)):append_text(" pkts")
offset = offset + 4
-- Handle Packets Receiving Rate(Pkts/sec)
subtree:add(fields.pack_rcv_rate, tvb(offset, 4)):append_text(" pkts/sec")
offset = offset + 4
-- Handle Estmated Link Capacity
subtree:add(fields.est_link_capacity, tvb(offset, 4)):append_text(" pkts/sec")
offset = offset + 4
-- Handle Receiving Rate(bps)
subtree:add(fields.rcv_rate, tvb(offset, 4)):append_text(" bps")
offset = offset + 4
end,
[3] = function()
pinfo.cols.info:append(" [NAK(loss Report)]")
pack_type_tree:append_text(" [NAK(loss Report)]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2))
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
-- Handle Additional Info, Timestamp and Destination Socket
parse_three_param()
-- Handle lost packet sequence
-- lua does not support changing loop variables within loops, but in the form of closures
-- https://blog.csdn.net/Ai102iA/article/details/75371239
local start = offset
local ending = tvb:len()
local lost_list_tree = subtree:add(fields.lost_list_tree, tvb(offset, ending - offset))
for start in function()
local first_bit = bit.rshift(tvb(start, 1):uint(), 7)
if first_bit == 1 then
local lost_pack_range_tree = lost_list_tree:add(fields.lost_pack_range_tree, tvb(start, 8))
local lost_start = bit.band(tvb(start, 4):uint(), 0x7FFFFFFF)
lost_pack_range_tree:append_text(" (" .. lost_start .. " -> " .. tvb(start + 4, 4):uint() .. ")")
lost_pack_range_tree:add(fields.lost_start, tvb(start, 4), lost_start)
start = start + 4
lost_pack_range_tree:add(fields.lost_up_to, tvb(start, 4))
start = start + 4
else
lost_list_tree:add(fields.lost_pack_seq, tvb(start, 4))
start = start + 4
end
return start
end
do
if start == ending then
break
end
end
end,
[4] = function()
pinfo.cols.info:append(" [Congestion Warning]")
pack_type_tree:append_text(" [Congestion Warning]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2))
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
end,
[5] = function()
pinfo.cols.info:append(" [Shutdown]")
pack_type_tree:append_text(" [Shutdown]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2))
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
-- Handle Additional Info, Timestamp and Destination Socket
parse_three_param()
end,
[6] = function()
pinfo.cols.info:append(" [ACKACK]")
pack_type_tree:append_text(" [ACKACK]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2))
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
-- Handle ACK sequence number
subtree:add(fields.ack_num, tvb(offset, 4))
offset = offset + 4
-- Handle Time Stamp
subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs")
offset = offset + 4
-- Handle Destination Socket
subtree:add(fields.dst_sock, tvb(offset, 4))
offset = offset + 4
-- Handle Control Information
subtree:add(fields.ctl_info, tvb(offset, 4))
offset = offset + 4
end,
[7] = function()
pinfo.cols.info:append(" [Drop Request]")
pack_type_tree:append_text(" [Drop Request]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Drop Request]")
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
end,
[8] = function()
pinfo.cols.info:append(" [Peer Error]")
pack_type_tree:append_text(" [Peer Error]")
pack_type_tree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Peer Error]")
pack_type_tree:add(fields.reserve, tvb(offset + 2, 2)):append_text(" [Undefined]")
offset = offset + 4
end
}
-- Handle based on msg_type
local case = switch[msg_type]
if case then
case()
else
-- default case
subtree:add(fields.msg_type, tvb(offset, 2)):append_text(" [Unknown Message Type]")
offset = offset + 4
end
else
-- If type field is '0x7FFF', it means an extended type, Handle Reserve field
offset = offset + 2
local msg_ext_type = tvb(offset, 2):uint()
if msg_ext_type == 0 then
pinfo.cols.info:append(" [Message Extension]")
pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Message Extension]")
offset = offset + 2
-- Handle Additional Info, Time Stamp and Destination Socket
parse_three_param()
-- Control information: defined by user
elseif msg_ext_type == 1 or ext_type == 2 then
if msg_ext_type == 1 then
pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [SRT Handshake Request]")
pinfo.cols.info:append(" [SRT Handshake Request]")
elseif msg_ext_type == 2 then
pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [SRT Handshake Response]")
pinfo.cols.info:append(" [SRT Handshake Response]")
end
offset = offset + 2
-- Ignore additional info (this field is not defined in this packet type)
subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]")
offset = offset + 4
-- Handle Time Stamp
subtree:add(fields.time_stamp, tvb(offset, 4)):append_text("μs")
offset = offset + 4
-- Handle Destination Socket
subtree:add(fields.dst_sock, tvb(offset, 4))
offset = offset + 4
-- Handle SRT Version field
subtree:add(fields.srt_version, tvb(offset, 4))
offset = ofssset + 4
-- Handle SRT Flags
local SRT_flags_tree = subtree:add(fields.srt_flags, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_tsbpdsnd, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_tsbpdrcv, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_haicrypt, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_tlpktdrop, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_nakreport, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_rexmitflg, tvb(offset, 4))
SRT_flags_tree:add(fields.srt_opt_stream, tvb(offset, 4))
offset = offset + 4
-- Handle TsbPd Resv
subtree:add(fields.tsbpb_resv, tvb(offset, 2))
offset = offset + 2
-- Handle TsbPb Delay
subtree:add(fields.tsbpb_delay, tvb(offset, 2))
offset = offset + 2
-- Handle Reserved field
subtree:add(fields.reserve, tvb(offset, 4))
offset = offset + 4
elseif msg_ext_type == 3 or msg_ext_type == 4 then
if msg_ext_type == 3 then
pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Encryption Keying Material Request]")
pinfo.cols.info:append(" [Encryption Keying Material Request]")
elseif msg_ext_type == 4 then
pack_type_tree:add(fields.msg_ext_type, tvb(offset, 2)):append_text(" [Encryption Keying Material Response]")
pinfo.cols.info:append(" [Encryption Keying Material Response]")
end
offset = offset + 2
-- Ignore additional info (this field is not defined in this packet type)
subtree:add(fields.additional_info, tvb(offset, 4)):append_text(" [undefined]")
offset = offset + 4
-- Handle Timestamp
subtree:add(fields.time_stamp, tvb(offset, 4)):append_text("μs")
offset = offset + 4
-- Handle Destination Socket
subtree:add(fields.dst_sock, tvb(offset, 4))
offset = offset + 4
-- Handle KmErr
if msg_ext_type == 4 then
subtree:add(fields.km_err, tvb(offset, 4))
offset = offset + 4
return
end
-- The encrypted message is not handled
end
end
else
-- 0 -> Data Packet
pack_type_tree:add(fields.pack_type, tvb(offset, 2))
pack_type_tree:append_text(" (Data Packet)")
local seq_num = tvb(offset, 4):uint()
pinfo.cols.info:append(" (Data Packet)(Seq Num:" .. seq_num .. ")")
-- The first 4 bytes are the package sequence number
subtree:add(fields.seq_num, tvb(offset, 4))
offset = offset + 4
data_flag_info_tree = subtree:add(fields.data_flag_info_tree, tvb(offset, 1))
-- Handle FF flag
local FF_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0xC0), 6)
if FF_state == 0 then
data_flag_info_tree:append_text(" [Middle packet]")
elseif FF_state == 1 then
data_flag_info_tree:append_text(" [Last packet]")
elseif FF_state == 2 then
data_flag_info_tree:append_text(" [First packet]")
else
data_flag_info_tree:append_text(" [Single packet]")
end
data_flag_info_tree:add(fields.FF_state, tvb(offset, 1))
-- Handle O flag
local O_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x20), 5)
if O_state == 0 then
data_flag_info_tree:append_text(" [Data delivered unordered]")
else
data_flag_info_tree:append_text(" [Data delivered in order]")
end
data_flag_info_tree:add(fields.O_state, tvb(offset, 1))
-- Handle KK flag
local KK_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x18), 3)
if KK_state == 1 then
data_flag_info_tree:append_text(" [Encrypted with even key]")
elseif KK_state == 2 then
data_flag_info_tree:append_text(" [Encrypted with odd key]")
end
data_flag_info_tree:add(fields.KK_state, tvb(offset, 1))
-- Handle R flag
local R_state = bit.rshift(bit.band(tvb(offset, 1):uint(), 0x04), 2)
if R_state == 1 then
data_flag_info_tree:append_text(" [Retransmit packet]")
pinfo.cols.info:append(" [Retransmit packet]")
end
data_flag_info_tree:add(fields.R_state, tvb(offset, 1))
-- Handle message number
local msg_num = tvb(offset, 4):uint()
msg_num = bit.band(tvb(offset, 4):uint(), 0x03FFFFFF)
-- subtree:add(fields.msg_num, bit.band(tvb(offset, 4):uint(), 0x03FFFFFF))
subtree:add(fields.msg_num, tvb(offset, 4), msg_num)
offset = offset + 4
-- Handle Timestamp
subtree:add(fields.time_stamp, tvb(offset, 4)):append_text(" μs")
offset = offset + 4
-- Handle destination socket
subtree:add(fields.dst_sock, tvb(offset, 4))
offset = offset + 4
end
end
-- Add the protocol into udp table
local port = 1935
local function enable_dissector()
DissectorTable.get("udp.port"):add(port, srt_dev)
end
-- Call it now - enabled by default
enable_dissector()
local function disable_dissector()
DissectorTable.get("udp.port"):remove(port, srt_dev)
end
-- Prefs changed will listen at new port
function srt_dev.prefs_changed()
if port ~= srt_dev.prefs.srt_udp_port then
if port ~= 0 then
disable_dissector()
end
port = srt_dev.prefs.srt_udp_port
if port ~= 0 then
enable_dissector()
end
end
end

View file

@ -41,7 +41,7 @@ proc ReadBack {fd} {
# Nothing more to read
if {$remain == 0} {
puts stderr "NOTHING MORE TO BE WRITTEN - exitting"
puts stderr "NOTHING MORE TO BE WRITTEN - exiting"
set ::theend 1
return
}

View file

@ -0,0 +1,10 @@
/* Copyright © 2023 Steve Lhomme */
/* SPDX-License-Identifier: ISC */
#include <windows.h>
#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600 /* _WIN32_WINNT_VISTA */
#error NOPE
#endif
int main(void)
{
return 0;
}

View file

@ -0,0 +1,10 @@
tmp
installers
*.exe
*~
~*
.#*
*.bak
*.autosave
.DS_Store
._*

View file

@ -0,0 +1,123 @@
# SRT Static Libraries Installer for Windows
This directory contains scripts to build a binary installer for
libsrt on Windows systems for Visual Studio applications using SRT.
## SRT developer: Building the libsrt installer
### Prerequisites
These first two steps need to be executed once only.
- Prerequisite 1: Install OpenSSL for Windows, both 64 and 32 bits.
This can be done automatically by running the PowerShell script `install-openssl.ps1`.
- Prerequisite 2: Install NSIS, the NullSoft Installation Scripting system.
This can be done automatically by running the PowerShell script `install-nsis.ps1`.
### Building the libsrt installer
To build the libsrt installer, simply run the PowerShell script `build-win-installer.ps1`.
Running it without parameters, for instance launching it from the Windows Explorer, is
sufficient to build the installer.
Optional parameters:
- `-Version name` :
Use the specified string as version number for libsrt. By default, if the
current commit has a tag, use that tag (initial "v" removed, for instance
`1.4.3`). Otherwise, the defaut version is a detailed version number (most
recent version, number of commits since then, short commit SHA, for instance
`1.4.3-32-g22cc924`). Use that option if necessary to specify some other
non-standard form of version string.
- `-NoPause` :
Do not wait for the user to press `<enter>` at end of execution. By default,
execute a `pause` instruction at the end of execution, which is useful
when the script was launched from Windows Explorer. Use that option when the
script is invoked from another PowerShell script.
The installer is then available in the directory `installers`.
The name of the installer is `libsrt-VERS.exe` where `VERS` is the SRT version number
(see the `-Version` option).
The installer shall then be published as a release asset in the `srt` repository
on GitHub, either as `libsrt-VERS.exe` or `libsrt-VERS-win-installer.zip`.
In the latter case, the archive shall contain `libsrt-VERS.exe`.
## SRT user: Using the libsrt installer
### Installing the SRT libraries
To install the SRT libraries, simply run the `libsrt-VERS.exe` installer which is
available in the [SRT release area](https://github.com/Haivision/srt/releases).
After installing the libsrt binaries, an environment variable named `LIBSRT` is
defined with the installation root (typically `C:\Program Files (x86)\libsrt`).
If there is a need for automation, in a CI/CD pipeline for instance, the download
of the latest `libsrt-VERS.exe` and its installation can be automated using the
sample PowerShell script `install-libsrt.ps1` which is available in this directory.
This script may be freely copied in the user's build environment.
When run without parameters (for instance from the Windows explorer), this
script downloads and installs the latest version of libsrt.
Optional parameters:
- `-Destination path` :
Specify a local directory where the libsrt package will be downloaded.
By default, use the `tmp` subdirectory from this script's directory.
- `-ForceDownload` :
Force a download even if the package is already downloaded in the
destination path. Note that the latest version is always checked.
If a older package is already present but a newer one is available
online, the newer one is always downloaded, even without this option.
- `-GitHubActions` :
When used in a GitHub Actions workflow, make sure that the `LIBSRT`
environment variable is propagated to subsequent jobs. In your GitHub
workflow, in the initial setup phase, use
`script-dir\install-libsrt.ps1 -GitHubActions -NoPause`.
- `-NoInstall` :
Do not install the package, only download it. By default, libsrt is installed.
- `-NoPause` :
Do not wait for the user to press `<enter>` at end of execution. By default,
execute a `pause` instruction at the end of execution, which is useful
when the script was launched from Windows Explorer. Use that option when the
script is invoked from another PowerShell script.
### Building Windows applications with libsrt
In the SRT installation root directory (specified in environment variable `LIBSRT`),
there is a Visual Studio property file named `libsrt.props`. Simply reference this
property file in your Visual Studio project to use libsrt.
You can also do that manually by editing the application project file (the XML
file named with a `.vcxproj` extension). Add the following line just before
the end of the file:
~~~
<Import Project="$(LIBSRT)\libsrt.props"/>
~~~
With this setup, just compile your application normally, either using the
Visual Studio IDE or the MSBuild command line tool.
## Files reference
This directory contains the following files:
| File name | Usage
| ----------------------- | -----
| build-win-installer.ps1 | PowerShell script to build the libsrt installer.
| install-libsrt.ps1 | Sample PowerShell script to automatically install libsrt (for user's projects).
| install-openssl.ps1 | PowerShell script to install OpenSSL (prerequisite to build the installer).
| install-nsis.ps1 | PowerShell script to install NSIS (prerequisite to build the installer).
| libsrt.nsi | NSIS installation script (used to build the installer).
| libsrt.props | Visual Studio property files to use libsrt (embedded in the installer).
| README.md | This text file.

View file

@ -0,0 +1,227 @@
#-----------------------------------------------------------------------------
#
# SRT - Secure, Reliable, Transport
# Copyright (c) 2021, Thierry Lelegard
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#-----------------------------------------------------------------------------
<#
.SYNOPSIS
Build the SRT static libraries installer for Windows.
.PARAMETER Version
Use the specified string as version number from libsrt. By default, if
the current commit has a tag, use that tag (initial 'v' removed). Otherwise,
the defaut version is a detailed version number (most recent version, number
of commits since then, short commit SHA).
.PARAMETER NoPause
Do not wait for the user to press <enter> at end of execution. By default,
execute a "pause" instruction at the end of execution, which is useful
when the script was run from Windows Explorer.
#>
[CmdletBinding()]
param(
[string]$Version = "",
[switch]$NoPause = $false
)
Write-Output "Building the SRT static libraries installer for Windows"
# Directory containing this script:
$ScriptDir = $PSScriptRoot
# The root of the srt repository is two levels up.
$RepoDir = (Split-Path -Parent (Split-Path -Parent $ScriptDir))
# Output directory for final installers:
$OutDir = "$ScriptDir\installers"
# Temporary directory for build operations:
$TmpDir = "$ScriptDir\tmp"
#-----------------------------------------------------------------------------
# A function to exit this script with optional error message, using -NoPause
#-----------------------------------------------------------------------------
function Exit-Script([string]$Message = "")
{
$Code = 0
if ($Message -ne "") {
Write-Output "ERROR: $Message"
$Code = 1
}
if (-not $NoPause) {
pause
}
exit $Code
}
#-----------------------------------------------------------------------------
# Build SRT version strings
#-----------------------------------------------------------------------------
# By default, let git format a decent version number.
if (-not $Version) {
$Version = (git describe --tags ) -replace '-g','-'
}
$Version = $Version -replace '^v',''
# Split version string in pieces and make sure to get at least four elements.
$VField = ($Version -split "[-\. ]") + @("0", "0", "0", "0") | Select-String -Pattern '^\d*$'
$VersionInfo = "$($VField[0]).$($VField[1]).$($VField[2]).$($VField[3])"
Write-Output "SRT version: $Version"
Write-Output "Windows version info: $VersionInfo"
#-----------------------------------------------------------------------------
# Initialization phase, verify prerequisites
#-----------------------------------------------------------------------------
# Locate OpenSSL root from local installation.
$SslRoot = @{
"x64" = "C:\Program Files\OpenSSL-Win64";
"Win32" = "C:\Program Files (x86)\OpenSSL-Win32"
}
# Verify OpenSSL directories.
$Missing = 0
foreach ($file in @($SslRoot["x64"], $SslRoot["Win32"])) {
if (-not (Test-Path $file)) {
Write-Output "**** Missing $file"
$Missing = $Missing + 1
}
}
if ($Missing -gt 0) {
Exit-Script "Missing $Missing OpenSSL files, use install-openssl.ps1 to install OpenSSL"
}
# Locate MSBuild and CMake, regardless of Visual Studio version.
Write-Output "Searching MSBuild ..."
$MSRoots = @("C:\Program Files*\MSBuild", "C:\Program Files*\Microsoft Visual Studio", "C:\Program Files*\CMake*")
$MSBuild = Get-ChildItem -Recurse -Path $MSRoots -Include MSBuild.exe -ErrorAction Ignore |
ForEach-Object { (Get-Command $_).FileVersionInfo } |
Sort-Object -Unique -Property FileVersion |
ForEach-Object { $_.FileName} |
Select-Object -Last 1
if (-not $MSBuild) {
Exit-Script "MSBuild not found"
}
Write-Output "Searching CMake ..."
$CMake = Get-ChildItem -Recurse -Path $MSRoots -Include cmake.exe -ErrorAction Ignore |
ForEach-Object { (Get-Command $_).FileVersionInfo } |
Sort-Object -Unique -Property FileVersion |
ForEach-Object { $_.FileName} |
Select-Object -Last 1
if (-not $CMake) {
Exit-Script "CMake not found, check option 'C++ CMake tools for Windows' in Visual Studio installer"
}
# Locate NSIS, the Nullsoft Scriptable Installation System.
Write-Output "Searching NSIS ..."
$NSIS = Get-Item "C:\Program Files*\NSIS\makensis.exe" | ForEach-Object { $_.FullName} | Select-Object -Last 1
if (-not $NSIS) {
Exit-Script "NSIS not found, use install-nsis.ps1 to install NSIS"
}
Write-Output "MSBuild: $MSBuild"
Write-Output "CMake: $CMake"
Write-Output "NSIS: $NSIS"
# Create the directories for builds when necessary.
[void](New-Item -Path $TmpDir -ItemType Directory -Force)
[void](New-Item -Path $OutDir -ItemType Directory -Force)
#-----------------------------------------------------------------------------
# Configure and build SRT library using CMake on two architectures.
#-----------------------------------------------------------------------------
foreach ($Platform in @("x64", "Win32")) {
# Build directory. Cleanup to force a fresh cmake config.
$BuildDir = "$TmpDir\build.$Platform"
Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $BuildDir
[void](New-Item -Path $BuildDir -ItemType Directory -Force)
# Run CMake.
Write-Output "Configuring build for platform $Platform ..."
$SRoot = $SslRoot[$Platform]
& $CMake -S $RepoDir -B $BuildDir -A $Platform `
-DENABLE_STDCXX_SYNC=ON `
-DOPENSSL_ROOT_DIR="$SRoot" `
-DOPENSSL_LIBRARIES="$SRoot\lib\libssl_static.lib;$SRoot\lib\libcrypto_static.lib" `
-DOPENSSL_INCLUDE_DIR="$SRoot\include"
# Patch version string in version.h
Get-Content "$BuildDir\version.h" |
ForEach-Object {
$_ -replace "#define *SRT_VERSION_STRING .*","#define SRT_VERSION_STRING `"$Version`""
} |
Out-File "$BuildDir\version.new" -Encoding ascii
Move-Item "$BuildDir\version.new" "$BuildDir\version.h" -Force
# Compile SRT.
Write-Output "Building for platform $Platform ..."
foreach ($Conf in @("Release", "Debug")) {
& $MSBuild "$BuildDir\SRT.sln" /nologo /maxcpucount /property:Configuration=$Conf /property:Platform=$Platform /target:srt_static
}
}
# Verify the presence of compiled libraries.
Write-Output "Checking compiled libraries ..."
$Missing = 0
foreach ($Conf in @("Release", "Debug")) {
foreach ($Platform in @("x64", "Win32")) {
$Path = "$TmpDir\build.$Platform\$Conf\srt_static.lib"
if (-not (Test-Path $Path)) {
Write-Output "**** Missing $Path"
$Missing = $Missing + 1
}
}
}
if ($Missing -gt 0) {
Exit-Script "Missing $Missing files"
}
#-----------------------------------------------------------------------------
# Build the binary installer.
#-----------------------------------------------------------------------------
$InstallExe = "$OutDir\libsrt-$Version.exe"
$InstallZip = "$OutDir\libsrt-$Version-win-installer.zip"
Write-Output "Building installer ..."
& $NSIS /V2 `
/DVersion="$Version" `
/DVersionInfo="$VersionInfo" `
/DOutDir="$OutDir" `
/DBuildRoot="$TmpDir" `
/DRepoDir="$RepoDir" `
"$ScriptDir\libsrt.nsi"
if (-not (Test-Path $InstallExe)) {
Exit-Script "**** Missing $InstallExe"
}
Write-Output "Building installer archive ..."
Remove-Item -Force -ErrorAction SilentlyContinue $InstallZip
Compress-Archive -Path $InstallExe -DestinationPath $InstallZip -CompressionLevel Optimal
if (-not (Test-Path $InstallZip)) {
Exit-Script "**** Missing $InstallZip"
}
Exit-Script

View file

@ -0,0 +1,131 @@
# SRT library download and install for Windows.
# Copyright (c) 2021, Thierry Lelegard
# All rights reserved.
<#
.SYNOPSIS
Download and install the libsrt library for Windows. This script is
provided to automate the build of Windows applications using libsrt.
.PARAMETER Destination
Specify a local directory where the libsrt package will be downloaded.
By default, use "tmp" subdirectory from this script.
.PARAMETER ForceDownload
Force a download even if the package is already downloaded.
.PARAMETER GitHubActions
When used in a GitHub Actions workflow, make sure that the LIBSRT
environment variable is propagated to subsequent jobs.
.PARAMETER NoInstall
Do not install the package. By default, libsrt is installed.
.PARAMETER NoPause
Do not wait for the user to press <enter> at end of execution. By default,
execute a "pause" instruction at the end of execution, which is useful
when the script was run from Windows Explorer.
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[string]$Destination = "",
[switch]$ForceDownload = $false,
[switch]$GitHubActions = $false,
[switch]$NoInstall = $false,
[switch]$NoPause = $false
)
Write-Output "libsrt download and installation procedure"
# Default directory for downloaded products.
if (-not $Destination) {
$Destination = "$PSScriptRoot\tmp"
}
# A function to exit this script.
function Exit-Script([string]$Message = "")
{
$Code = 0
if ($Message -ne "") {
Write-Output "ERROR: $Message"
$Code = 1
}
if (-not $NoPause) {
pause
}
exit $Code
}
# Without this, Invoke-WebRequest is awfully slow.
$ProgressPreference = 'SilentlyContinue'
# Get the URL of the latest libsrt installer.
$URL = (Invoke-RestMethod "https://api.github.com/repos/Haivision/srt/releases?per_page=20" |
ForEach-Object { $_.assets } |
ForEach-Object { $_.browser_download_url } |
Select-String @("/libsrt-.*\.exe$", "/libsrt-.*-win-installer\.zip$") |
Select-Object -First 1)
if (-not $URL) {
Exit-Script "Could not find a libsrt installer on GitHub"
}
if (-not ($URL -match "\.zip$") -and -not ($URL -match "\.exe$")) {
Exit-Script "Unexpected URL, not .exe, not .zip: $URL"
}
# Installer name and path.
$InstName = (Split-Path -Leaf $URL)
$InstPath = "$Destination\$InstName"
# Create the directory for downloaded products when necessary.
[void](New-Item -Path $Destination -ItemType Directory -Force)
# Download installer
if (-not $ForceDownload -and (Test-Path $InstPath)) {
Write-Output "$InstName already downloaded, use -ForceDownload to download again"
}
else {
Write-Output "Downloading $URL ..."
Invoke-WebRequest $URL.ToString() -UseBasicParsing -UserAgent Download -OutFile $InstPath
if (-not (Test-Path $InstPath)) {
Exit-Script "$URL download failed"
}
}
# If installer is an archive, expect an exe with same name inside.
if ($InstName -match "\.zip$") {
# Expected installer name in archive.
$ZipName = $InstName
$ZipPath = $InstPath
$InstName = $ZipName -replace '-win-installer.zip','.exe'
$InstPath = "$Destination\$InstName"
# Extract the installer.
Remove-Item -Force $InstPath -ErrorAction SilentlyContinue
Write-Output "Expanding $ZipName ..."
Expand-Archive $ZipPath -DestinationPath $Destination
if (-not (Test-Path $InstPath)) {
Exit-Script "$InstName not found in $ZipName"
}
}
# Install libsrt
if (-not $NoInstall) {
Write-Output "Installing $InstName"
Start-Process -FilePath $InstPath -ArgumentList @("/S") -Wait
}
# Propagate LIBSRT in next jobs for GitHub Actions.
if ($GitHubActions -and (-not -not $env:GITHUB_ENV) -and (Test-Path $env:GITHUB_ENV)) {
$libsrt = [System.Environment]::GetEnvironmentVariable("LIBSRT","Machine")
Write-Output "LIBSRT=$libsrt" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
}
Exit-Script

View file

@ -0,0 +1,122 @@
#-----------------------------------------------------------------------------
#
# SRT - Secure, Reliable, Transport
# Copyright (c) 2021, Thierry Lelegard
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#-----------------------------------------------------------------------------
<#
.SYNOPSIS
Download, expand and install NSIS, the NullSoft Installer Scripting.
.PARAMETER ForceDownload
Force a download even if NSIS is already downloaded.
.PARAMETER NoInstall
Do not install the NSIS package. By default, NSIS is installed.
.PARAMETER NoPause
Do not wait for the user to press <enter> at end of execution. By default,
execute a "pause" instruction at the end of execution, which is useful
when the script was run from Windows Explorer.
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[switch]$ForceDownload = $false,
[switch]$NoInstall = $false,
[switch]$NoPause = $false
)
Write-Output "NSIS download and installation procedure"
$NSISPage = "https://nsis.sourceforge.io/Download"
$FallbackURL = "http://prdownloads.sourceforge.net/nsis/nsis-3.05-setup.exe?download"
# A function to exit this script.
function Exit-Script([string]$Message = "")
{
$Code = 0
if ($Message -ne "") {
Write-Output "ERROR: $Message"
$Code = 1
}
if (-not $NoPause) {
pause
}
exit $Code
}
# Local file names.
$RootDir = $PSScriptRoot
$TmpDir = "$RootDir\tmp"
# Create the directory for external products when necessary.
[void] (New-Item -Path $TmpDir -ItemType Directory -Force)
# Without this, Invoke-WebRequest is awfully slow.
$ProgressPreference = 'SilentlyContinue'
# Get the HTML page for NSIS downloads.
$status = 0
$message = ""
$Ref = $null
try {
$response = Invoke-WebRequest -UseBasicParsing -UserAgent Download -Uri $NSISPage
$status = [int] [Math]::Floor($response.StatusCode / 100)
}
catch {
$message = $_.Exception.Message
}
if ($status -ne 1 -and $status -ne 2) {
# Error fetch NSIS download page.
if ($message -eq "" -and (Test-Path variable:response)) {
Write-Output "Status code $($response.StatusCode), $($response.StatusDescription)"
}
else {
Write-Output "#### Error accessing ${NSISPage}: $message"
}
}
else {
# Parse HTML page to locate the latest installer.
$Ref = $response.Links.href | Where-Object { $_ -like "*/nsis-*-setup.exe?download" } | Select-Object -First 1
}
if (-not $Ref) {
# Could not find a reference to NSIS installer.
$Url = [System.Uri]$FallbackURL
}
else {
# Build the absolute URL's from base URL (the download page) and href links.
$Url = New-Object -TypeName 'System.Uri' -ArgumentList ([System.Uri]$NSISPage, $Ref)
}
$InstallerName = (Split-Path -Leaf $Url.LocalPath)
$InstallerPath = "$TmpDir\$InstallerName"
# Download installer
if (-not $ForceDownload -and (Test-Path $InstallerPath)) {
Write-Output "$InstallerName already downloaded, use -ForceDownload to download again"
}
else {
Write-Output "Downloading $Url ..."
Invoke-WebRequest -UseBasicParsing -UserAgent Download -Uri $Url -OutFile $InstallerPath
if (-not (Test-Path $InstallerPath)) {
Exit-Script "$Url download failed"
}
}
# Install NSIS
if (-not $NoInstall) {
Write-Output "Installing $InstallerName"
Start-Process -FilePath $InstallerPath -ArgumentList @("/S") -Wait
}
Exit-Script

View file

@ -0,0 +1,119 @@
#-----------------------------------------------------------------------------
#
# SRT - Secure, Reliable, Transport
# Copyright (c) 2021, Thierry Lelegard
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#-----------------------------------------------------------------------------
<#
.SYNOPSIS
Download, expand and install OpenSSL for Windows.
.PARAMETER ForceDownload
Force a download even if the OpenSSL installers are already downloaded.
.PARAMETER NoInstall
Do not install the OpenSSL packages. By default, OpenSSL is installed.
.PARAMETER NoPause
Do not wait for the user to press <enter> at end of execution. By default,
execute a "pause" instruction at the end of execution, which is useful
when the script was run from Windows Explorer.
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param(
[switch]$ForceDownload = $false,
[switch]$NoInstall = $false,
[switch]$NoPause = $false
)
Write-Output "OpenSSL download and installation procedure"
$OpenSSLHomePage = "http://slproweb.com/products/Win32OpenSSL.html"
# A function to exit this script.
function Exit-Script([string]$Message = "")
{
$Code = 0
if ($Message -ne "") {
Write-Output "ERROR: $Message"
$Code = 1
}
if (-not $NoPause) {
pause
}
exit $Code
}
# Local file names.
$RootDir = $PSScriptRoot
$TmpDir = "$RootDir\tmp"
# Create the directory for external products when necessary.
[void] (New-Item -Path $TmpDir -ItemType Directory -Force)
# Without this, Invoke-WebRequest is awfully slow.
$ProgressPreference = 'SilentlyContinue'
# Get the HTML page for OpenSSL downloads.
$status = 0
$message = ""
try {
$response = Invoke-WebRequest -UseBasicParsing -UserAgent Download -Uri $OpenSSLHomePage
$status = [int] [Math]::Floor($response.StatusCode / 100)
}
catch {
$message = $_.Exception.Message
}
if ($status -ne 1 -and $status -ne 2) {
if ($message -eq "" -and (Test-Path variable:response)) {
Exit-Script "Status code $($response.StatusCode), $($response.StatusDescription)"
}
else {
Exit-Script "#### Error accessing ${OpenSSLHomePage}: $message"
}
}
# Parse HTML page to locate the latest MSI files.
$Ref32 = $response.Links.href | Where-Object { $_ -like "*/Win32OpenSSL-*.msi" } | Select-Object -First 1
$Ref64 = $response.Links.href | Where-Object { $_ -like "*/Win64OpenSSL-*.msi" } | Select-Object -First 1
# Build the absolute URL's from base URL (the download page) and href links.
$Url32 = New-Object -TypeName 'System.Uri' -ArgumentList ([System.Uri]$OpenSSLHomePage, $Ref32)
$Url64 = New-Object -TypeName 'System.Uri' -ArgumentList ([System.Uri]$OpenSSLHomePage, $Ref64)
# Download and install one MSI package.
function Download-Install([string]$Url)
{
$MsiName = (Split-Path -Leaf $Url.toString())
$MsiPath = "$TmpDir\$MsiName"
if (-not $ForceDownload -and (Test-Path $MsiPath)) {
Write-Output "$MsiName already downloaded, use -ForceDownload to download again"
}
else {
Write-Output "Downloading $Url ..."
Invoke-WebRequest -UseBasicParsing -UserAgent Download -Uri $Url -OutFile $MsiPath
}
if (-not (Test-Path $MsiPath)) {
Exit-Script "$Url download failed"
}
if (-not $NoInstall) {
Write-Output "Installing $MsiName"
Start-Process msiexec.exe -ArgumentList @("/i", $MsiPath, "/qn", "/norestart") -Wait
}
}
# Download and install the two MSI packages.
Download-Install $Url32
Download-Install $Url64
Exit-Script

View file

@ -0,0 +1,219 @@
;-----------------------------------------------------------------------------
;
; SRT - Secure, Reliable, Transport
; Copyright (c) 2021, Thierry Lelegard
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;
;-----------------------------------------------------------------------------
;
; NSIS script to build the SRT binary installer for Windows.
; Do not invoke NSIS directly, use PowerShell script build-win-installer.ps1
; to ensure that all parameters are properly passed.
;
;-----------------------------------------------------------------------------
Name "SRT"
Caption "SRT Libraries Installer"
!verbose push
!verbose 0
!include "MUI2.nsh"
!include "Sections.nsh"
!include "TextFunc.nsh"
!include "FileFunc.nsh"
!include "WinMessages.nsh"
!include "x64.nsh"
!verbose pop
!define ProductName "libsrt"
!define Build32Dir "${BuildRoot}\build.Win32"
!define Build64Dir "${BuildRoot}\build.x64"
!define SSL32Dir "C:\Program Files (x86)\OpenSSL-Win32"
!define SSL64Dir "C:\Program Files\OpenSSL-Win64"
; Installer file information.
VIProductVersion ${VersionInfo}
VIAddVersionKey ProductName "${ProductName}"
VIAddVersionKey ProductVersion "${Version}"
VIAddVersionKey Comments "The SRT static libraries for Visual C++ on Windows"
VIAddVersionKey CompanyName "Haivision"
VIAddVersionKey LegalCopyright "Copyright (c) 2021 Haivision Systems Inc."
VIAddVersionKey FileVersion "${VersionInfo}"
VIAddVersionKey FileDescription "SRT Installer"
; Name of binary installer file.
OutFile "${OutDir}\${ProductName}-${Version}.exe"
; Generate a Unicode installer (default is ANSI).
Unicode true
; Registry key for environment variables
!define EnvironmentKey '"SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
; Registry entry for product info and uninstallation info.
!define ProductKey "Software\${ProductName}"
!define UninstallKey "Software\Microsoft\Windows\CurrentVersion\Uninstall\${ProductName}"
; Use XP manifest.
XPStyle on
; Request administrator privileges for Windows Vista and higher.
RequestExecutionLevel admin
; "Modern User Interface" (MUI) settings.
!define MUI_ABORTWARNING
; Default installation folder.
InstallDir "$PROGRAMFILES\${ProductName}"
; Get installation folder from registry if available from a previous installation.
InstallDirRegKey HKLM "${ProductKey}" "InstallDir"
; Installer pages.
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
; Uninstaller pages.
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
; Languages.
!insertmacro MUI_LANGUAGE "English"
; Installation initialization.
function .onInit
; In 64-bit installers, don't use registry redirection.
${If} ${RunningX64}
SetRegView 64
${EndIf}
functionEnd
; Uninstallation initialization.
function un.onInit
; In 64-bit installers, don't use registry redirection.
${If} ${RunningX64}
SetRegView 64
${EndIf}
functionEnd
; Installation section
Section "Install"
; Work on "all users" context, not current user.
SetShellVarContext all
; Delete obsolete files from previous versions.
Delete "$INSTDIR\LICENSE.pthread.txt"
Delete "$INSTDIR\include\srt\srt4udt.h"
Delete "$INSTDIR\include\srt\udt.h"
Delete "$INSTDIR\lib\Release-x64\pthread.lib"
Delete "$INSTDIR\lib\Release-Win32\pthread.lib"
Delete "$INSTDIR\lib\Debug-x64\srt.pdb"
Delete "$INSTDIR\lib\Debug-x64\pthread.pdb"
Delete "$INSTDIR\lib\Debug-x64\pthread.lib"
Delete "$INSTDIR\lib\Debug-Win32\srt.pdb"
Delete "$INSTDIR\lib\Debug-Win32\pthread.pdb"
Delete "$INSTDIR\lib\Debug-Win32\pthread.lib"
SetOutPath "$INSTDIR"
File /oname=LICENSE.txt "${RepoDir}\LICENSE"
File "libsrt.props"
; Header files.
CreateDirectory "$INSTDIR\include\srt"
SetOutPath "$INSTDIR\include\srt"
File "${RepoDir}\srtcore\access_control.h"
File "${RepoDir}\srtcore\logging_api.h"
File "${RepoDir}\srtcore\platform_sys.h"
File "${RepoDir}\srtcore\srt.h"
File "${RepoDir}\srtcore\udt.h"
File "${Build64Dir}\version.h"
CreateDirectory "$INSTDIR\include\win"
SetOutPath "$INSTDIR\include\win"
File "${RepoDir}\common\win\syslog_defs.h"
; Libraries.
CreateDirectory "$INSTDIR\lib"
CreateDirectory "$INSTDIR\lib\Release-x64"
SetOutPath "$INSTDIR\lib\Release-x64"
File /oname=srt.lib "${Build64Dir}\Release\srt_static.lib"
File /oname=libcrypto.lib "${SSL64Dir}\lib\VC\static\libcrypto64MD.lib"
File /oname=libssl.lib "${SSL64Dir}\lib\VC\static\libssl64MD.lib"
CreateDirectory "$INSTDIR\lib\Debug-x64"
SetOutPath "$INSTDIR\lib\Debug-x64"
File /oname=srt.lib "${Build64Dir}\Debug\srt_static.lib"
File /oname=libcrypto.lib "${SSL64Dir}\lib\VC\static\libcrypto64MDd.lib"
File /oname=libssl.lib "${SSL64Dir}\lib\VC\static\libssl64MDd.lib"
CreateDirectory "$INSTDIR\lib\Release-Win32"
SetOutPath "$INSTDIR\lib\Release-Win32"
File /oname=srt.lib "${Build32Dir}\Release\srt_static.lib"
File /oname=libcrypto.lib "${SSL32Dir}\lib\VC\static\libcrypto32MD.lib"
File /oname=libssl.lib "${SSL32Dir}\lib\VC\static\libssl32MD.lib"
CreateDirectory "$INSTDIR\lib\Debug-Win32"
SetOutPath "$INSTDIR\lib\Debug-Win32"
File /oname=srt.lib "${Build32Dir}\Debug\srt_static.lib"
File /oname=libcrypto.lib "${SSL32Dir}\lib\VC\static\libcrypto32MDd.lib"
File /oname=libssl.lib "${SSL32Dir}\lib\VC\static\libssl32MDd.lib"
; Add an environment variable to installation root.
WriteRegStr HKLM ${EnvironmentKey} "LIBSRT" "$INSTDIR"
; Store installation folder in registry.
WriteRegStr HKLM "${ProductKey}" "InstallDir" $INSTDIR
; Create uninstaller
WriteUninstaller "$INSTDIR\Uninstall.exe"
; Declare uninstaller in "Add/Remove Software" control panel
WriteRegStr HKLM "${UninstallKey}" "DisplayName" "${ProductName}"
WriteRegStr HKLM "${UninstallKey}" "Publisher" "Haivision"
WriteRegStr HKLM "${UninstallKey}" "URLInfoAbout" "https://github.com/Haivision/srt"
WriteRegStr HKLM "${UninstallKey}" "DisplayVersion" "${Version}"
WriteRegStr HKLM "${UninstallKey}" "DisplayIcon" "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "${UninstallKey}" "UninstallString" "$INSTDIR\Uninstall.exe"
; Get estimated size of installed files
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "${UninstallKey}" "EstimatedSize" "$0"
; Notify applications of environment modifications
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd
; Uninstallation section
Section "Uninstall"
; Work on "all users" context, not current user.
SetShellVarContext all
; Get installation folder from registry
ReadRegStr $0 HKLM "${ProductKey}" "InstallDir"
; Delete product registry entries
DeleteRegKey HKCU "${ProductKey}"
DeleteRegKey HKLM "${ProductKey}"
DeleteRegKey HKLM "${UninstallKey}"
DeleteRegValue HKLM ${EnvironmentKey} "LIBSRT"
; Delete product files.
RMDir /r "$0\include"
RMDir /r "$0\lib"
Delete "$0\libsrt.props"
Delete "$0\LICENSE*"
Delete "$0\Uninstall.exe"
RMDir "$0"
; Notify applications of environment modifications
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
SectionEnd

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Visual Studio or MSBuild property file to use SRT static library -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Normalize platform name to x64 and Win32 (some projects use x86 or Win64) -->
<Choose>
<When Condition="'$(Platform)' == 'x86'">
<PropertyGroup Label="UserMacros">
<SrtPlatform>Win32</SrtPlatform>
</PropertyGroup>
</When>
<When Condition="'$(Platform)' == 'Win64'">
<PropertyGroup Label="UserMacros">
<SrtPlatform>x64</SrtPlatform>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Label="UserMacros">
<SrtPlatform>$(Platform)</SrtPlatform>
</PropertyGroup>
</Otherwise>
</Choose>
<!-- Compilation and link options -->
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(LIBSRT)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>srt.lib;libssl.lib;libcrypto.lib;crypt32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>$(LIBSRT)\lib\$(Configuration)-$(SrtPlatform);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalOptions>/ignore:4099 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
</Project>