Compare commits
	
		
			31 Commits
		
	
	
		
			tray_test1
			...
			bb510b685a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					bb510b685a | ||
| 
						 | 
					876f482391 | ||
| 
						 | 
					42dd6d16d7 | ||
| 
						 | 
					11ae259f67 | ||
| 
						 | 
					f2027befc8 | ||
| 
						 | 
					9777cb81cb | ||
| 
						 | 
					84ade4d683 | ||
| 
						 | 
					f89aeae62b | ||
| 
						 | 
					c68a9a2245 | ||
| 
						 | 
					1a12447804 | ||
| 
						 | 
					02600a3bc6 | ||
| 
						 | 
					1faa7e5510 | ||
| 
						 | 
					a0cc3c3fe7 | ||
| 
						 | 
					f97134b841 | ||
| 
						 | 
					8777539c2c | ||
| 
						 | 
					5708a83ba6 | ||
| 
						 | 
					2d54a3111c | ||
| 
						 | 
					1cd1390901 | ||
| 
						 | 
					3fbbf80e8c | ||
| 
						 | 
					281e681bf8 | ||
| 
						 | 
					9277ef34f6 | ||
| 
						 | 
					9bf9753bd1 | ||
| 
						 | 
					326d72a965 | ||
| 
						 | 
					cae0ab9c5c | ||
| 765340a727 | |||
| 72d3575670 | |||
| 31352ed06a | |||
| 2d96139d4a | |||
| 92740c8dbe | |||
| a9d8c070bc | |||
| f93602e524 | 
							
								
								
									
										8
									
								
								.github/workflows/cd.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/cd.yml
									
									
									
									
										vendored
									
									
								
							@@ -25,7 +25,7 @@ jobs:
 | 
			
		||||
      run: sudo apt update && sudo apt -y install libsodium-dev cmake libvpx-dev libopus-dev
 | 
			
		||||
 | 
			
		||||
    - name: Configure CMake
 | 
			
		||||
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DTOMATO_TOX_AV=ON
 | 
			
		||||
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DTOMATO_BREAKPAD=ON -DTOMATO_TOX_AV=ON -DCMAKE_EXE_LINKER_FLAGS=-gz
 | 
			
		||||
 | 
			
		||||
    - name: Build
 | 
			
		||||
      run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
 | 
			
		||||
@@ -64,6 +64,8 @@ jobs:
 | 
			
		||||
    strategy:
 | 
			
		||||
      matrix:
 | 
			
		||||
        platform:
 | 
			
		||||
          - vcpkg_toolkit: arm-neon-android
 | 
			
		||||
            ndk_abi: armeabi-v7a
 | 
			
		||||
          - vcpkg_toolkit: arm64-android
 | 
			
		||||
            ndk_abi: arm64-v8a
 | 
			
		||||
          - vcpkg_toolkit: x64-android
 | 
			
		||||
@@ -101,7 +103,7 @@ jobs:
 | 
			
		||||
    - name: Configure CMake
 | 
			
		||||
      env:
 | 
			
		||||
        ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}}
 | 
			
		||||
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=${{matrix.platform.vcpkg_toolkit}} -DANDROID=1 -DANDROID_PLATFORM=23 -DANDROID_ABI=${{matrix.platform.ndk_abi}} -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{steps.setup_ndk.outputs.ndk-path}}/build/cmake/android.toolchain.cmake -DSDLIMAGE_JPG_SHARED=OFF -DSDLIMAGE_PNG_SHARED=OFF -DTOMATO_MAIN_SO=ON -DTOMATO_TOX_AV=ON
 | 
			
		||||
      run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=/usr/local/share/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=${{matrix.platform.vcpkg_toolkit}} -DANDROID=1 -DANDROID_PLATFORM=23 -DANDROID_ABI=${{matrix.platform.ndk_abi}} -DVCPKG_CHAINLOAD_TOOLCHAIN_FILE=${{steps.setup_ndk.outputs.ndk-path}}/build/cmake/android.toolchain.cmake -DSDLIMAGE_JPG_SHARED=OFF -DSDLIMAGE_PNG_SHARED=OFF -DTOMATO_MAIN_SO=ON -DTOMATO_TOX_AV=ON -DCMAKE_EXE_LINKER_FLAGS=-gz
 | 
			
		||||
 | 
			
		||||
    - name: Build (tomato)
 | 
			
		||||
      run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4 -t tomato
 | 
			
		||||
@@ -164,7 +166,7 @@ jobs:
 | 
			
		||||
    #- uses: ilammy/setup-nasm@v1
 | 
			
		||||
 | 
			
		||||
    - name: Configure CMake
 | 
			
		||||
      run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDLIMAGE_VENDORED=ON -DSDLIMAGE_DEPS_SHARED=ON -DSDLIMAGE_JXL=OFF -DSDLIMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DTOMATO_TOX_AV=ON
 | 
			
		||||
      run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DSDLIMAGE_VENDORED=ON -DSDLIMAGE_DEPS_SHARED=ON -DSDLIMAGE_JXL=OFF -DSDLIMAGE_AVIF=OFF -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe -DTOMATO_BREAKPAD=ON -DTOMATO_TOX_AV=ON
 | 
			
		||||
 | 
			
		||||
    - name: Build
 | 
			
		||||
      run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -t tomato
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							@@ -38,6 +38,8 @@ jobs:
 | 
			
		||||
    strategy:
 | 
			
		||||
      matrix:
 | 
			
		||||
        platform:
 | 
			
		||||
          - vcpkg_toolkit: arm-neon-android
 | 
			
		||||
            ndk_abi: armeabi-v7a
 | 
			
		||||
          - vcpkg_toolkit: arm64-android
 | 
			
		||||
            ndk_abi: arm64-v8a
 | 
			
		||||
          - vcpkg_toolkit: x64-android
 | 
			
		||||
@@ -59,9 +61,9 @@ jobs:
 | 
			
		||||
        distribution: 'temurin'
 | 
			
		||||
        java-version: '17'
 | 
			
		||||
 | 
			
		||||
    - name: update vcpkg
 | 
			
		||||
      run: |
 | 
			
		||||
        git clone https://github.com/microsoft/vcpkg.git
 | 
			
		||||
    #- name: update vcpkg
 | 
			
		||||
    #  run: |
 | 
			
		||||
    #    git clone https://github.com/microsoft/vcpkg.git
 | 
			
		||||
 | 
			
		||||
    - name: Install Dependencies (host)
 | 
			
		||||
      run: sudo apt update && sudo apt -y install cmake pkg-config nasm
 | 
			
		||||
@@ -69,7 +71,8 @@ jobs:
 | 
			
		||||
    - name: Install Dependencies (target)
 | 
			
		||||
      env:
 | 
			
		||||
        ANDROID_NDK_HOME: ${{steps.setup_ndk.outputs.ndk-path}}
 | 
			
		||||
      run: vcpkg install --triplet ${{matrix.platform.vcpkg_toolkit}} --overlay-ports=vcpkg/ports libsodium opus libvpx libpng libjpeg-turbo
 | 
			
		||||
      #run: vcpkg install --triplet ${{matrix.platform.vcpkg_toolkit}} --overlay-ports=vcpkg/ports libsodium opus libvpx libpng libjpeg-turbo
 | 
			
		||||
      run: vcpkg install --triplet ${{matrix.platform.vcpkg_toolkit}} libsodium opus libvpx libpng libjpeg-turbo
 | 
			
		||||
 | 
			
		||||
    # vcpkg scripts root /usr/local/share/vcpkg/scripts
 | 
			
		||||
    - name: Configure CMake
 | 
			
		||||
 
 | 
			
		||||
@@ -20,9 +20,9 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
 | 
			
		||||
 | 
			
		||||
option(TOMATO_MAIN_SO "Build tomato as a shared object (for eg android apps)" ANDROID)
 | 
			
		||||
option(TOMATO_ASAN "Build tomato with asan (gcc/clang/msvc)" OFF)
 | 
			
		||||
option(TOMATO_BREAKPAD "Build tomato with breakpad crash dumping" OFF)
 | 
			
		||||
option(TOMATO_TOX_AV "Build tomato with ToxAV" OFF)
 | 
			
		||||
 | 
			
		||||
message("II TOMATO_TOX_AV: ${TOMATO_TOX_AV}")
 | 
			
		||||
 | 
			
		||||
if (TOMATO_ASAN)
 | 
			
		||||
	if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
 | 
			
		||||
@@ -43,6 +43,17 @@ if (TOMATO_ASAN)
 | 
			
		||||
	endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
message("II TOMATO_BREAKPAD: ${TOMATO_BREAKPAD}")
 | 
			
		||||
if (TOMATO_BREAKPAD)
 | 
			
		||||
	if (LINUX) # TODO: test if android
 | 
			
		||||
		# HACK: workaround an ugly cmake bug,
 | 
			
		||||
		# where subdirs can now propergate enable_language upwards
 | 
			
		||||
		enable_language(ASM)
 | 
			
		||||
	endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
message("II TOMATO_TOX_AV: ${TOMATO_TOX_AV}")
 | 
			
		||||
 | 
			
		||||
# uggly, but it needs to be defined for all of tomato.
 | 
			
		||||
# but this also means that we can not compile tomato in the same cmake as plugins
 | 
			
		||||
add_compile_definitions(ENTT_API_EXPORT)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								external/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								external/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -24,3 +24,7 @@ add_subdirectory(./libwebp)
 | 
			
		||||
add_subdirectory(./qoi)
 | 
			
		||||
add_subdirectory(./sdl_image)
 | 
			
		||||
 | 
			
		||||
if (TOMATO_BREAKPAD)
 | 
			
		||||
	add_subdirectory(./breakpad)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										139
									
								
								external/breakpad/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								external/breakpad/CMakeLists.txt
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
cmake_minimum_required(VERSION 3.16...3.24 FATAL_ERROR)
 | 
			
		||||
 | 
			
		||||
include(FetchContent)
 | 
			
		||||
 | 
			
		||||
if (NOT TARGET breakpad_client)
 | 
			
		||||
 | 
			
		||||
	if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Android")
 | 
			
		||||
		if (NOT TARGET lss)
 | 
			
		||||
			FetchContent_Declare(lss
 | 
			
		||||
				GIT_REPOSITORY https://chromium.googlesource.com/linux-syscall-support/
 | 
			
		||||
				GIT_TAG 9719c1e1e676814c456b55f5f070eabad6709d31
 | 
			
		||||
 | 
			
		||||
				FIND_PACKAGE_ARGS # for the future
 | 
			
		||||
			)
 | 
			
		||||
			FetchContent_GetProperties(lss)
 | 
			
		||||
			if(NOT lss_POPULATED)
 | 
			
		||||
				FetchContent_Populate(lss)
 | 
			
		||||
 | 
			
		||||
				# HACK: breakpad expects this at a specific path
 | 
			
		||||
				configure_file(
 | 
			
		||||
					${lss_SOURCE_DIR}/linux_syscall_support.h
 | 
			
		||||
					${CMAKE_CURRENT_BINARY_DIR}/third_party/lss/linux_syscall_support.h
 | 
			
		||||
					@ONLY
 | 
			
		||||
				)
 | 
			
		||||
 | 
			
		||||
				add_library(lss INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/third_party/lss/linux_syscall_support.h)
 | 
			
		||||
				target_include_directories(lss INTERFACE ${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
			endif()
 | 
			
		||||
		endif()
 | 
			
		||||
	endif()
 | 
			
		||||
 | 
			
		||||
	FetchContent_Declare(breakpad
 | 
			
		||||
		GIT_REPOSITORY https://chromium.googlesource.com/breakpad/breakpad
 | 
			
		||||
		GIT_TAG v2023.06.01
 | 
			
		||||
 | 
			
		||||
		FIND_PACKAGE_ARGS # for the future
 | 
			
		||||
	)
 | 
			
		||||
	FetchContent_GetProperties(breakpad)
 | 
			
		||||
	if(NOT breakpad_POPULATED)
 | 
			
		||||
		FetchContent_Populate(breakpad)
 | 
			
		||||
 | 
			
		||||
		add_library(breakpad_common STATIC
 | 
			
		||||
			${breakpad_SOURCE_DIR}/src/common/convert_UTF.h
 | 
			
		||||
			${breakpad_SOURCE_DIR}/src/common/convert_UTF.cc
 | 
			
		||||
			${breakpad_SOURCE_DIR}/src/common/md5.h
 | 
			
		||||
			${breakpad_SOURCE_DIR}/src/common/md5.cc
 | 
			
		||||
			${breakpad_SOURCE_DIR}/src/common/string_conversion.h
 | 
			
		||||
			${breakpad_SOURCE_DIR}/src/common/string_conversion.cc
 | 
			
		||||
		)
 | 
			
		||||
		target_include_directories(breakpad_common PUBLIC "${breakpad_SOURCE_DIR}/src")
 | 
			
		||||
 | 
			
		||||
		if (WIN32)
 | 
			
		||||
			target_sources(breakpad_common PUBLIC
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/windows/guid_string.h
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/windows/guid_string.cc
 | 
			
		||||
			)
 | 
			
		||||
 | 
			
		||||
			add_library(breakpad_client STATIC)
 | 
			
		||||
			target_sources(breakpad_client
 | 
			
		||||
				PUBLIC
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/windows/handler/exception_handler.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/windows/common/ipc_protocol.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/windows/crash_generation/crash_generation_client.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/windows/crash_generation/minidump_generator.h
 | 
			
		||||
				PRIVATE
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/windows/handler/exception_handler.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/windows/crash_generation/crash_generation_client.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/windows/crash_generation/minidump_generator.cc
 | 
			
		||||
			)
 | 
			
		||||
			target_compile_definitions(breakpad_client PRIVATE UNICODE)
 | 
			
		||||
		#elseif() # TODO: mac, ios and any other platform
 | 
			
		||||
		else() # assume linux
 | 
			
		||||
			enable_language(ASM) # mostly to document, needs to be set in parent
 | 
			
		||||
			target_sources(breakpad_common PUBLIC
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/elf_core_dump.cc
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/elfutils.h
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/elfutils.cc
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/file_id.h
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/file_id.cc
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/guid_creator.h
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/guid_creator.cc
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/linux_libc_support.cc
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/memory_mapped_file.cc
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/safe_readlink.cc
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/breakpad_getcontext.h
 | 
			
		||||
				${breakpad_SOURCE_DIR}/src/common/linux/breakpad_getcontext.S
 | 
			
		||||
			)
 | 
			
		||||
			#set_property(SOURCE ${breakpad_SOURCE_DIR}/src/common/linux/breakpad_getcontext.S APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp")
 | 
			
		||||
 | 
			
		||||
			add_library(breakpad_client STATIC)
 | 
			
		||||
			target_sources(breakpad_client
 | 
			
		||||
				PUBLIC
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/handler/exception_handler.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/handler/minidump_descriptor.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/crash_generation/crash_generation_client.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/log/log.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/microdump_writer/microdump_writer.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/minidump_writer.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/pe_file.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/pe_structs.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/proc_cpuinfo_reader.h
 | 
			
		||||
				PRIVATE
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/handler/exception_handler.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/handler/minidump_descriptor.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/crash_generation/crash_generation_client.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/crash_generation/crash_generation_server.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/log/log.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/microdump_writer/microdump_writer.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/dump_writer_common/thread_info.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/dump_writer_common/ucontext_reader.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/minidump_writer.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/linux_core_dumper.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/linux_dumper.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/linux_ptrace_dumper.cc
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/linux/minidump_writer/pe_file.cc
 | 
			
		||||
			)
 | 
			
		||||
		endif()
 | 
			
		||||
 | 
			
		||||
		if (TARGET lss)
 | 
			
		||||
			target_link_libraries(breakpad_common PUBLIC lss)
 | 
			
		||||
			target_link_libraries(breakpad_client PUBLIC lss)
 | 
			
		||||
		endif()
 | 
			
		||||
 | 
			
		||||
		if (TARGET breakpad_client)
 | 
			
		||||
			if (NOT WIN32)
 | 
			
		||||
				target_sources(breakpad_client PUBLIC
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/minidump_file_writer-inl.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/minidump_file_writer.h
 | 
			
		||||
					${breakpad_SOURCE_DIR}/src/client/minidump_file_writer.cc
 | 
			
		||||
				)
 | 
			
		||||
			endif()
 | 
			
		||||
			target_link_libraries(breakpad_client PUBLIC breakpad_common)
 | 
			
		||||
			target_include_directories(breakpad_client PUBLIC "${breakpad_SOURCE_DIR}/src")
 | 
			
		||||
			target_compile_features(breakpad_client PUBLIC cxx_std_11)
 | 
			
		||||
		endif()
 | 
			
		||||
	endif()
 | 
			
		||||
	#FetchContent_MakeAvailable(breakpad)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								external/sdl/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								external/sdl/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -25,7 +25,9 @@ if (NOT TARGET SDL3::SDL3)
 | 
			
		||||
		#GIT_TAG 6e885d96193a4b0096fe7fed6d4e6c3e5f247283 # tip 09-09-2024
 | 
			
		||||
		#GIT_TAG 9dd8859240703d886941733ad32c1dc6f50d64f0 # tip 19-09-2024
 | 
			
		||||
		#GIT_TAG afdf325fb4090e93a124519d1a3bc1fbe0ba9025 # bad
 | 
			
		||||
		GIT_TAG e292d1f5ace469f718d7b6b4dec8c28e37dcaa0e # tip 05-10-2024 (3.1.3)
 | 
			
		||||
		#GIT_TAG e292d1f5ace469f718d7b6b4dec8c28e37dcaa0e # tip 05-10-2024 (3.1.3)
 | 
			
		||||
		#GIT_TAG 2654d5d48b8f764148a7c246fea85b32b1133578 # tip 18-10-2024
 | 
			
		||||
		GIT_TAG f8468d580d903e106640800034a4721aca24264c # tip 15-11-2024
 | 
			
		||||
 | 
			
		||||
		FIND_PACKAGE_ARGS # for the future
 | 
			
		||||
	)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								external/solanaceae_message_serializer
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								external/solanaceae_message_serializer
									
									
									
									
										vendored
									
									
								
							 Submodule external/solanaceae_message_serializer updated: e574c4f779...c5ee5ac3f9
									
								
							
							
								
								
									
										2
									
								
								external/solanaceae_object_store
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								external/solanaceae_object_store
									
									
									
									
										vendored
									
									
								
							 Submodule external/solanaceae_object_store updated: 2801fc21fb...18d2888e34
									
								
							
							
								
								
									
										2
									
								
								external/solanaceae_tox
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								external/solanaceae_tox
									
									
									
									
										vendored
									
									
								
							 Submodule external/solanaceae_tox updated: a0c3336f37...cd196562af
									
								
							
							
								
								
									
										2
									
								
								external/solanaceae_toxcore
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								external/solanaceae_toxcore
									
									
									
									
										vendored
									
									
								
							 Submodule external/solanaceae_toxcore updated: 7cd6a2b0de...727c341899
									
								
							
							
								
								
									
										2
									
								
								external/solanaceae_util
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								external/solanaceae_util
									
									
									
									
										vendored
									
									
								
							 Submodule external/solanaceae_util updated: 17d2baf736...85bbbb0e5a
									
								
							
							
								
								
									
										12
									
								
								external/toxcore/c-toxcore/.cirrus.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								external/toxcore/c-toxcore/.cirrus.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,6 @@
 | 
			
		||||
---
 | 
			
		||||
bazel-opt_task:
 | 
			
		||||
  timeout_in: 5m
 | 
			
		||||
  container:
 | 
			
		||||
    image: toxchat/toktok-stack:latest-release
 | 
			
		||||
    cpu: 2
 | 
			
		||||
@@ -7,9 +8,9 @@ bazel-opt_task:
 | 
			
		||||
  configure_script:
 | 
			
		||||
    - git submodule update --init --recursive
 | 
			
		||||
    - /src/workspace/tools/inject-repo c-toxcore
 | 
			
		||||
    - sed -i -e 's/build --config=remote/#&/' /src/workspace/.bazelrc.local
 | 
			
		||||
  test_all_script:
 | 
			
		||||
    - cd /src/workspace && bazel test -k
 | 
			
		||||
        --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST
 | 
			
		||||
        --build_tag_filters=-haskell
 | 
			
		||||
        --test_tag_filters=-haskell
 | 
			
		||||
        --
 | 
			
		||||
@@ -17,6 +18,7 @@ bazel-opt_task:
 | 
			
		||||
        -//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections.
 | 
			
		||||
 | 
			
		||||
bazel-dbg_task:
 | 
			
		||||
  timeout_in: 5m
 | 
			
		||||
  container:
 | 
			
		||||
    image: toxchat/toktok-stack:latest-debug
 | 
			
		||||
    cpu: 2
 | 
			
		||||
@@ -26,14 +28,15 @@ bazel-dbg_task:
 | 
			
		||||
    - /src/workspace/tools/inject-repo c-toxcore
 | 
			
		||||
  test_all_script:
 | 
			
		||||
    - cd /src/workspace && bazel test -k
 | 
			
		||||
        --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST
 | 
			
		||||
        --build_tag_filters=-haskell
 | 
			
		||||
        --test_tag_filters=-haskell
 | 
			
		||||
        --remote_http_cache=http://$CIRRUS_HTTP_CACHE_HOST
 | 
			
		||||
        --
 | 
			
		||||
        //c-toxcore/...
 | 
			
		||||
        -//c-toxcore/auto_tests:tcp_relay_test # Cirrus doesn't allow external network connections.
 | 
			
		||||
 | 
			
		||||
cimple_task:
 | 
			
		||||
  timeout_in: 5m
 | 
			
		||||
  container:
 | 
			
		||||
    image: toxchat/toktok-stack:latest-release
 | 
			
		||||
    cpu: 2
 | 
			
		||||
@@ -41,17 +44,18 @@ cimple_task:
 | 
			
		||||
  configure_script:
 | 
			
		||||
    - git submodule update --init --recursive
 | 
			
		||||
    - /src/workspace/tools/inject-repo c-toxcore
 | 
			
		||||
    - sed -i -e 's/build --config=remote/#&/' /src/workspace/.bazelrc.local
 | 
			
		||||
  test_all_script:
 | 
			
		||||
    - cd /src/workspace && bazel test -k
 | 
			
		||||
        --remote_cache=http://$CIRRUS_HTTP_CACHE_HOST
 | 
			
		||||
        --build_tag_filters=haskell
 | 
			
		||||
        --test_tag_filters=haskell
 | 
			
		||||
        --
 | 
			
		||||
        //c-toxcore/...
 | 
			
		||||
 | 
			
		||||
freebsd_task:
 | 
			
		||||
  timeout_in: 5m
 | 
			
		||||
  freebsd_instance:
 | 
			
		||||
    image_family: freebsd-14-0
 | 
			
		||||
    image_family: freebsd-14-1
 | 
			
		||||
  configure_script:
 | 
			
		||||
    - PAGER=cat ASSUME_ALWAYS_YES=YES pkg install
 | 
			
		||||
        cmake
 | 
			
		||||
 
 | 
			
		||||
@@ -36,9 +36,6 @@ add_flag -Wno-padded
 | 
			
		||||
# This warns on things like _XOPEN_SOURCE, which we currently need (we
 | 
			
		||||
# probably won't need these in the future).
 | 
			
		||||
add_flag -Wno-reserved-id-macro
 | 
			
		||||
# TODO(iphydf): Clean these up. They are likely not bugs, but still
 | 
			
		||||
# potential issues and probably confusing.
 | 
			
		||||
add_flag -Wno-sign-compare
 | 
			
		||||
# We don't want to have default cases, we want to explicitly define all cases
 | 
			
		||||
add_flag -Wno-switch-default
 | 
			
		||||
# __attribute__((nonnull)) causes this warning on defensive null checks.
 | 
			
		||||
 
 | 
			
		||||
@@ -47,8 +47,7 @@ add_flag -Wunused-value
 | 
			
		||||
 | 
			
		||||
# struct Foo foo = {0}; is a common idiom.
 | 
			
		||||
add_flag -Wno-missing-field-initializers
 | 
			
		||||
# TODO(iphydf): Clean these up. They are likely not bugs, but still
 | 
			
		||||
# potential issues and probably confusing.
 | 
			
		||||
# Checked by clang, but gcc is warning when it's not necessary.
 | 
			
		||||
add_flag -Wno-sign-compare
 | 
			
		||||
# File transfer code has this.
 | 
			
		||||
add_flag -Wno-type-limits
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								external/toxcore/c-toxcore/.github/workflows/release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								external/toxcore/c-toxcore/.github/workflows/release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
name: release
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [master]
 | 
			
		||||
  pull_request_target:
 | 
			
		||||
    branches: [master]
 | 
			
		||||
    types: [opened, reopened, synchronize]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  release:
 | 
			
		||||
    uses: TokTok/ci-tools/.github/workflows/release-drafter.yml@master
 | 
			
		||||
							
								
								
									
										2
									
								
								external/toxcore/c-toxcore/.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								external/toxcore/c-toxcore/.gitmodules
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,3 @@
 | 
			
		||||
[submodule "third_party/cmp"]
 | 
			
		||||
	path = third_party/cmp
 | 
			
		||||
	url = https://github.com/camgunz/cmp
 | 
			
		||||
	url = https://github.com/TokTok/cmp
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								external/toxcore/c-toxcore/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								external/toxcore/c-toxcore/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@@ -161,7 +161,7 @@ option(DHT_BOOTSTRAP "Enable building of DHT_bootstrap" ON)
 | 
			
		||||
option(BOOTSTRAP_DAEMON "Enable building of tox-bootstrapd" ON)
 | 
			
		||||
if(BOOTSTRAP_DAEMON AND WIN32)
 | 
			
		||||
  message(WARNING "Building tox-bootstrapd for Windows is not supported, disabling")
 | 
			
		||||
  set(BOOTSTRAP_DAEMON OFF)
 | 
			
		||||
  set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
option(BUILD_FUZZ_TESTS "Build fuzzing harnesses" OFF)
 | 
			
		||||
@@ -177,6 +177,7 @@ include(Dependencies)
 | 
			
		||||
 | 
			
		||||
if(MUST_BUILD_TOXAV)
 | 
			
		||||
  set(NO_TOXAV_ERROR_TYPE SEND_ERROR)
 | 
			
		||||
  set(BUILD_TOXAV ON CACHE BOOL "" FORCE)
 | 
			
		||||
else()
 | 
			
		||||
  set(NO_TOXAV_ERROR_TYPE WARNING)
 | 
			
		||||
endif()
 | 
			
		||||
@@ -184,11 +185,11 @@ endif()
 | 
			
		||||
if(BUILD_TOXAV)
 | 
			
		||||
  if(NOT OPUS_FOUND)
 | 
			
		||||
    message(${NO_TOXAV_ERROR_TYPE} "Option BUILD_TOXAV is enabled but required library OPUS was not found.")
 | 
			
		||||
    set(BUILD_TOXAV OFF)
 | 
			
		||||
    set(BUILD_TOXAV OFF CACHE BOOL "" FORCE)
 | 
			
		||||
  endif()
 | 
			
		||||
  if(NOT VPX_FOUND)
 | 
			
		||||
    message(${NO_TOXAV_ERROR_TYPE} "Option BUILD_TOXAV is enabled but required library VPX was not found.")
 | 
			
		||||
    set(BUILD_TOXAV OFF)
 | 
			
		||||
    set(BUILD_TOXAV OFF CACHE BOOL "" FORCE)
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
@@ -391,6 +392,7 @@ if(BUILD_TOXAV)
 | 
			
		||||
    toxav/rtp.h
 | 
			
		||||
    toxav/toxav.c
 | 
			
		||||
    toxav/toxav.h
 | 
			
		||||
    toxav/toxav_hacks.h
 | 
			
		||||
    toxav/toxav_old.c
 | 
			
		||||
    toxav/video.c
 | 
			
		||||
    toxav/video.h)
 | 
			
		||||
@@ -597,7 +599,7 @@ if(BOOTSTRAP_DAEMON)
 | 
			
		||||
    add_subdirectory(other/bootstrap_daemon)
 | 
			
		||||
  else()
 | 
			
		||||
    message(WARNING "Option BOOTSTRAP_DAEMON is enabled but required library LIBCONFIG was not found.")
 | 
			
		||||
    set(BOOTSTRAP_DAEMON OFF)
 | 
			
		||||
    set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE)
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -420,7 +420,7 @@ static void test_groupav(AutoTox *autotoxes)
 | 
			
		||||
        tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != UINT32_MAX,
 | 
			
		||||
    ck_assert_msg(toxav_add_av_groupchat(autotoxes[0].tox, audio_callback, &autotoxes[0]) != -1,
 | 
			
		||||
                  "failed to create group");
 | 
			
		||||
    printf("tox #%u: inviting its first friend\n", autotoxes[0].index);
 | 
			
		||||
    ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend");
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ static void handle_conference_invite(
 | 
			
		||||
 | 
			
		||||
    ck_assert_msg(!state->joined, "invitation callback generated for already joined conference");
 | 
			
		||||
 | 
			
		||||
    if (friend_number != -1) {
 | 
			
		||||
    if (friend_number != UINT32_MAX) {
 | 
			
		||||
        Tox_Err_Conference_Join err;
 | 
			
		||||
        state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
 | 
			
		||||
        ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@ static void handle_conference_invite(
 | 
			
		||||
    const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
 | 
			
		||||
    const size_t length = tox_event_conference_invite_get_cookie_length(event);
 | 
			
		||||
 | 
			
		||||
    if (friend_number != -1) {
 | 
			
		||||
    if (friend_number != UINT32_MAX) {
 | 
			
		||||
        Tox_Err_Conference_Join err;
 | 
			
		||||
        state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
 | 
			
		||||
        ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
 | 
			
		||||
 
 | 
			
		||||
@@ -168,29 +168,33 @@ static void test_av_three_calls(void)
 | 
			
		||||
    Time_Data time_data;
 | 
			
		||||
    pthread_mutex_init(&time_data.lock, nullptr);
 | 
			
		||||
    {
 | 
			
		||||
        Tox_Options *opts = tox_options_new(nullptr);
 | 
			
		||||
        ck_assert(opts != nullptr);
 | 
			
		||||
        tox_options_set_experimental_thread_safety(opts, true);
 | 
			
		||||
        Tox_Err_New error;
 | 
			
		||||
 | 
			
		||||
        bootstrap = tox_new_log(nullptr, &error, &index[0]);
 | 
			
		||||
        bootstrap = tox_new_log(opts, &error, &index[0]);
 | 
			
		||||
        ck_assert(error == TOX_ERR_NEW_OK);
 | 
			
		||||
 | 
			
		||||
        time_data.clock = current_time_monotonic(bootstrap->mono_time);
 | 
			
		||||
        set_current_time_callback(bootstrap, &time_data);
 | 
			
		||||
 | 
			
		||||
        alice = tox_new_log(nullptr, &error, &index[1]);
 | 
			
		||||
        alice = tox_new_log(opts, &error, &index[1]);
 | 
			
		||||
        ck_assert(error == TOX_ERR_NEW_OK);
 | 
			
		||||
        set_current_time_callback(alice, &time_data);
 | 
			
		||||
 | 
			
		||||
        bobs[0] = tox_new_log(nullptr, &error, &index[2]);
 | 
			
		||||
        bobs[0] = tox_new_log(opts, &error, &index[2]);
 | 
			
		||||
        ck_assert(error == TOX_ERR_NEW_OK);
 | 
			
		||||
        set_current_time_callback(bobs[0], &time_data);
 | 
			
		||||
 | 
			
		||||
        bobs[1] = tox_new_log(nullptr, &error, &index[3]);
 | 
			
		||||
        bobs[1] = tox_new_log(opts, &error, &index[3]);
 | 
			
		||||
        ck_assert(error == TOX_ERR_NEW_OK);
 | 
			
		||||
        set_current_time_callback(bobs[1], &time_data);
 | 
			
		||||
 | 
			
		||||
        bobs[2] = tox_new_log(nullptr, &error, &index[4]);
 | 
			
		||||
        bobs[2] = tox_new_log(opts, &error, &index[4]);
 | 
			
		||||
        ck_assert(error == TOX_ERR_NEW_OK);
 | 
			
		||||
        set_current_time_callback(bobs[2], &time_data);
 | 
			
		||||
        tox_options_free(opts);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf("Created 5 instances of Tox\n");
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,6 @@ run() {
 | 
			
		||||
    -Wno-missing-noreturn \
 | 
			
		||||
    -Wno-old-style-cast \
 | 
			
		||||
    -Wno-padded \
 | 
			
		||||
    -Wno-sign-compare \
 | 
			
		||||
    -Wno-switch-default \
 | 
			
		||||
    -Wno-tautological-pointer-compare \
 | 
			
		||||
    -Wno-unreachable-code-return \
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,6 @@ CPPCHECK+=("--suppress=knownConditionTrueFalse")
 | 
			
		||||
CPPCHECK+=("--suppress=missingIncludeSystem")
 | 
			
		||||
# TODO(iphydf): Maybe fix?
 | 
			
		||||
CPPCHECK+=("--suppress=signConversion")
 | 
			
		||||
# TODO(iphydf): Fixed in the toxav refactor PR.
 | 
			
		||||
CPPCHECK+=("--suppress=redundantAssignment")
 | 
			
		||||
 | 
			
		||||
# We use this for VLAs.
 | 
			
		||||
CPPCHECK_CXX+=("--suppress=allocaCalled")
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +5,11 @@ FROM alpine:3.19.0 AS build
 | 
			
		||||
RUN ["apk", "--no-cache", "add",\
 | 
			
		||||
 "clang",\
 | 
			
		||||
 "cmake",\
 | 
			
		||||
 "linux-headers",\
 | 
			
		||||
 "libconfig-dev",\
 | 
			
		||||
 "libconfig-static",\
 | 
			
		||||
 "libsodium-dev",\
 | 
			
		||||
 "libsodium-static",\
 | 
			
		||||
 "linux-headers",\
 | 
			
		||||
 "musl-dev",\
 | 
			
		||||
 "ninja",\
 | 
			
		||||
 "python3"]
 | 
			
		||||
 
 | 
			
		||||
@@ -138,9 +138,20 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// A wrapper function that actually takes a bool argument
 | 
			
		||||
static int tox_config_lookup_bool(const config_t *config, const char *path, bool *bool_value)
 | 
			
		||||
{
 | 
			
		||||
    int int_value = 0;
 | 
			
		||||
    if (config_lookup_bool(config, path, &int_value) == CONFIG_FALSE) {
 | 
			
		||||
        return CONFIG_FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    *bool_value = int_value != 0;
 | 
			
		||||
    return CONFIG_TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port,
 | 
			
		||||
                        int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay,
 | 
			
		||||
                        uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd)
 | 
			
		||||
                        bool *enable_ipv6, bool *enable_ipv4_fallback, bool *enable_lan_discovery, bool *enable_tcp_relay,
 | 
			
		||||
                        uint16_t **tcp_relay_ports, int *tcp_relay_port_count, bool *enable_motd, char **motd)
 | 
			
		||||
{
 | 
			
		||||
    config_t cfg;
 | 
			
		||||
 | 
			
		||||
@@ -207,14 +218,14 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
 | 
			
		||||
    memcpy(*keys_file_path, tmp_keys_file, keys_file_path_len);
 | 
			
		||||
 | 
			
		||||
    // Get IPv6 option
 | 
			
		||||
    if (config_lookup_bool(&cfg, NAME_ENABLE_IPV6, enable_ipv6) == CONFIG_FALSE) {
 | 
			
		||||
    if (tox_config_lookup_bool(&cfg, NAME_ENABLE_IPV6, enable_ipv6) == CONFIG_FALSE) {
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV6);
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV6, DEFAULT_ENABLE_IPV6 ? "true" : "false");
 | 
			
		||||
        *enable_ipv6 = DEFAULT_ENABLE_IPV6;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get IPv4 fallback option
 | 
			
		||||
    if (config_lookup_bool(&cfg, NAME_ENABLE_IPV4_FALLBACK, enable_ipv4_fallback) == CONFIG_FALSE) {
 | 
			
		||||
    if (tox_config_lookup_bool(&cfg, NAME_ENABLE_IPV4_FALLBACK, enable_ipv4_fallback) == CONFIG_FALSE) {
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_IPV4_FALLBACK);
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_IPV4_FALLBACK,
 | 
			
		||||
                  DEFAULT_ENABLE_IPV4_FALLBACK ? "true" : "false");
 | 
			
		||||
@@ -222,7 +233,7 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get LAN discovery option
 | 
			
		||||
    if (config_lookup_bool(&cfg, NAME_ENABLE_LAN_DISCOVERY, enable_lan_discovery) == CONFIG_FALSE) {
 | 
			
		||||
    if (tox_config_lookup_bool(&cfg, NAME_ENABLE_LAN_DISCOVERY, enable_lan_discovery) == CONFIG_FALSE) {
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_LAN_DISCOVERY);
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_LAN_DISCOVERY,
 | 
			
		||||
                  DEFAULT_ENABLE_LAN_DISCOVERY ? "true" : "false");
 | 
			
		||||
@@ -230,28 +241,28 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get TCP relay option
 | 
			
		||||
    if (config_lookup_bool(&cfg, NAME_ENABLE_TCP_RELAY, enable_tcp_relay) == CONFIG_FALSE) {
 | 
			
		||||
    if (tox_config_lookup_bool(&cfg, NAME_ENABLE_TCP_RELAY, enable_tcp_relay) == CONFIG_FALSE) {
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_TCP_RELAY);
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_TCP_RELAY,
 | 
			
		||||
                  DEFAULT_ENABLE_TCP_RELAY ? "true" : "false");
 | 
			
		||||
        *enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (*enable_tcp_relay != 0) {
 | 
			
		||||
    if (*enable_tcp_relay) {
 | 
			
		||||
        parse_tcp_relay_ports_config(&cfg, tcp_relay_ports, tcp_relay_port_count);
 | 
			
		||||
    } else {
 | 
			
		||||
        *tcp_relay_port_count = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get MOTD option
 | 
			
		||||
    if (config_lookup_bool(&cfg, NAME_ENABLE_MOTD, enable_motd) == CONFIG_FALSE) {
 | 
			
		||||
    if (tox_config_lookup_bool(&cfg, NAME_ENABLE_MOTD, enable_motd) == CONFIG_FALSE) {
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "No '%s' setting in configuration file.\n", NAME_ENABLE_MOTD);
 | 
			
		||||
        log_write(LOG_LEVEL_WARNING, "Using default '%s': %s\n", NAME_ENABLE_MOTD,
 | 
			
		||||
                  DEFAULT_ENABLE_MOTD ? "true" : "false");
 | 
			
		||||
        *enable_motd = DEFAULT_ENABLE_MOTD;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (*enable_motd != 0) {
 | 
			
		||||
    if (*enable_motd) {
 | 
			
		||||
        // Get MOTD
 | 
			
		||||
        const char *tmp_motd;
 | 
			
		||||
 | 
			
		||||
@@ -273,14 +284,14 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_PID_FILE_PATH,        *pid_file_path);
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_KEYS_FILE_PATH,       *keys_file_path);
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %d\n", NAME_PORT,                 *port);
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6,          *enable_ipv6          != 0 ? "true" : "false");
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback != 0 ? "true" : "false");
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery != 0 ? "true" : "false");
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV6,          *enable_ipv6          ? "true" : "false");
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_IPV4_FALLBACK, *enable_ipv4_fallback ? "true" : "false");
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_LAN_DISCOVERY, *enable_lan_discovery ? "true" : "false");
 | 
			
		||||
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY,     *enable_tcp_relay     != 0 ? "true" : "false");
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY,     *enable_tcp_relay     ? "true" : "false");
 | 
			
		||||
 | 
			
		||||
    // Show info about tcp ports only if tcp relay is enabled
 | 
			
		||||
    if (*enable_tcp_relay != 0) {
 | 
			
		||||
    if (*enable_tcp_relay) {
 | 
			
		||||
        if (*tcp_relay_port_count == 0) {
 | 
			
		||||
            log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n");
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -292,9 +303,9 @@ bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD,          *enable_motd          != 0 ? "true" : "false");
 | 
			
		||||
    log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD,          *enable_motd          ? "true" : "false");
 | 
			
		||||
 | 
			
		||||
    if (*enable_motd != 0) {
 | 
			
		||||
    if (*enable_motd) {
 | 
			
		||||
        log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,14 +17,14 @@
 | 
			
		||||
 *
 | 
			
		||||
 * Important: You are responsible for freeing `pid_file_path` and `keys_file_path`
 | 
			
		||||
 *            also, iff `tcp_relay_ports_count` > 0, then you are responsible for freeing `tcp_relay_ports`
 | 
			
		||||
 *            and also `motd` iff `enable_motd` is set.
 | 
			
		||||
 *            and also `motd` iff `enable_motd` is true.
 | 
			
		||||
 *
 | 
			
		||||
 * @return true on success,
 | 
			
		||||
 *         false on failure, doesn't modify any data pointed by arguments.
 | 
			
		||||
 */
 | 
			
		||||
bool get_general_config(const char *cfg_file_path, char **pid_file_path, char **keys_file_path, int *port,
 | 
			
		||||
                        int *enable_ipv6, int *enable_ipv4_fallback, int *enable_lan_discovery, int *enable_tcp_relay,
 | 
			
		||||
                        uint16_t **tcp_relay_ports, int *tcp_relay_port_count, int *enable_motd, char **motd);
 | 
			
		||||
                        bool *enable_ipv6, bool *enable_ipv4_fallback, bool *enable_lan_discovery, bool *enable_tcp_relay,
 | 
			
		||||
                        uint16_t **tcp_relay_ports, int *tcp_relay_port_count, bool *enable_motd, char **motd);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Bootstraps off nodes listed in the config file.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 * Copyright © 2016-2023 The TokTok team.
 | 
			
		||||
 * Copyright © 2016-2024 The TokTok team.
 | 
			
		||||
 * Copyright © 2014-2016 Tox project.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@@ -10,17 +10,19 @@
 | 
			
		||||
#ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H
 | 
			
		||||
#define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
#include "global.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_PID_FILE_PATH         "tox-bootstrapd.pid"
 | 
			
		||||
#define DEFAULT_KEYS_FILE_PATH        "tox-bootstrapd.keys"
 | 
			
		||||
#define DEFAULT_PORT                  33445
 | 
			
		||||
#define DEFAULT_ENABLE_IPV6           1 // 1 - true, 0 - false
 | 
			
		||||
#define DEFAULT_ENABLE_IPV4_FALLBACK  1 // 1 - true, 0 - false
 | 
			
		||||
#define DEFAULT_ENABLE_LAN_DISCOVERY  1 // 1 - true, 0 - false
 | 
			
		||||
#define DEFAULT_ENABLE_TCP_RELAY      1 // 1 - true, 0 - false
 | 
			
		||||
#define DEFAULT_ENABLE_IPV6           true
 | 
			
		||||
#define DEFAULT_ENABLE_IPV4_FALLBACK  true
 | 
			
		||||
#define DEFAULT_ENABLE_LAN_DISCOVERY  true
 | 
			
		||||
#define DEFAULT_ENABLE_TCP_RELAY      true
 | 
			
		||||
#define DEFAULT_TCP_RELAY_PORTS       443, 3389, 33445 // comma-separated list of ports
 | 
			
		||||
#define DEFAULT_ENABLE_MOTD           1 // 1 - true, 0 - false
 | 
			
		||||
#define DEFAULT_ENABLE_MOTD           true
 | 
			
		||||
#define DEFAULT_MOTD                  DAEMON_NAME
 | 
			
		||||
 | 
			
		||||
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_DEFAULTS_H
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 * Copyright © 2016-2018 The TokTok team.
 | 
			
		||||
 * Copyright © 2016-2024 The TokTok team.
 | 
			
		||||
 * Copyright © 2014-2016 Tox project.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@@ -240,13 +240,13 @@ int main(int argc, char *argv[])
 | 
			
		||||
    char *pid_file_path = nullptr;
 | 
			
		||||
    char *keys_file_path = nullptr;
 | 
			
		||||
    int start_port = 0;
 | 
			
		||||
    int enable_ipv6 = 0;
 | 
			
		||||
    int enable_ipv4_fallback = 0;
 | 
			
		||||
    int enable_lan_discovery = 0;
 | 
			
		||||
    int enable_tcp_relay = 0;
 | 
			
		||||
    bool enable_ipv6 = false;
 | 
			
		||||
    bool enable_ipv4_fallback = false;
 | 
			
		||||
    bool enable_lan_discovery = false;
 | 
			
		||||
    bool enable_tcp_relay = false;
 | 
			
		||||
    uint16_t *tcp_relay_ports = nullptr;
 | 
			
		||||
    int tcp_relay_port_count = 0;
 | 
			
		||||
    int enable_motd = 0;
 | 
			
		||||
    bool enable_motd = false;
 | 
			
		||||
    char *motd = nullptr;
 | 
			
		||||
 | 
			
		||||
    if (get_general_config(cfg_file_path, &pid_file_path, &keys_file_path, &start_port, &enable_ipv6, &enable_ipv4_fallback,
 | 
			
		||||
@@ -281,7 +281,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
    free(pid_file_path);
 | 
			
		||||
 | 
			
		||||
    IP ip;
 | 
			
		||||
    ip_init(&ip, enable_ipv6 != 0);
 | 
			
		||||
    ip_init(&ip, enable_ipv6);
 | 
			
		||||
 | 
			
		||||
    Logger *logger = logger_new();
 | 
			
		||||
 | 
			
		||||
@@ -296,10 +296,10 @@ int main(int argc, char *argv[])
 | 
			
		||||
    Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
 | 
			
		||||
 | 
			
		||||
    if (net == nullptr) {
 | 
			
		||||
        if (enable_ipv6 != 0 && enable_ipv4_fallback != 0) {
 | 
			
		||||
        if (enable_ipv6 && enable_ipv4_fallback) {
 | 
			
		||||
            log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
 | 
			
		||||
            enable_ipv6 = 0;
 | 
			
		||||
            ip_init(&ip, enable_ipv6 != 0);
 | 
			
		||||
            enable_ipv6 = false;
 | 
			
		||||
            ip_init(&ip, enable_ipv6);
 | 
			
		||||
            net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
 | 
			
		||||
 | 
			
		||||
            if (net == nullptr) {
 | 
			
		||||
@@ -334,7 +334,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
    mono_time_update(mono_time);
 | 
			
		||||
 | 
			
		||||
    DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery != 0);
 | 
			
		||||
    DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery);
 | 
			
		||||
 | 
			
		||||
    if (dht == nullptr) {
 | 
			
		||||
        log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
 | 
			
		||||
@@ -429,7 +429,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
    gca_onion_init(group_announce, onion_a);
 | 
			
		||||
 | 
			
		||||
    if (enable_motd != 0) {
 | 
			
		||||
    if (enable_motd) {
 | 
			
		||||
        if (bootstrap_set_callbacks(dht_get_net(dht), DAEMON_VERSION_NUMBER, (uint8_t *)motd, strlen(motd) + 1) == 0) {
 | 
			
		||||
            log_write(LOG_LEVEL_INFO, "Set MOTD successfully.\n");
 | 
			
		||||
            free(motd);
 | 
			
		||||
@@ -472,7 +472,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
    TCP_Server *tcp_server = nullptr;
 | 
			
		||||
 | 
			
		||||
    if (enable_tcp_relay != 0) {
 | 
			
		||||
    if (enable_tcp_relay) {
 | 
			
		||||
        if (tcp_relay_port_count == 0) {
 | 
			
		||||
            log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
 | 
			
		||||
            kill_onion_announce(onion_a);
 | 
			
		||||
@@ -488,7 +488,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
            return 1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6 != 0,
 | 
			
		||||
        tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6,
 | 
			
		||||
                                    tcp_relay_port_count, tcp_relay_ports,
 | 
			
		||||
                                    dht_get_self_secret_key(dht), onion, forwarding);
 | 
			
		||||
 | 
			
		||||
@@ -535,7 +535,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6 != 0)) {
 | 
			
		||||
    if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) {
 | 
			
		||||
        log_write(LOG_LEVEL_INFO, "List of bootstrap nodes read successfully.\n");
 | 
			
		||||
    } else {
 | 
			
		||||
        log_write(LOG_LEVEL_ERROR, "Couldn't read list of bootstrap nodes in %s. Exiting.\n", cfg_file_path);
 | 
			
		||||
@@ -561,7 +561,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
    Broadcast_Info *broadcast = nullptr;
 | 
			
		||||
 | 
			
		||||
    if (enable_lan_discovery != 0) {
 | 
			
		||||
    if (enable_lan_discovery) {
 | 
			
		||||
        broadcast = lan_discovery_init(ns);
 | 
			
		||||
        log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
 | 
			
		||||
    }
 | 
			
		||||
@@ -589,12 +589,12 @@ int main(int argc, char *argv[])
 | 
			
		||||
 | 
			
		||||
        do_dht(dht);
 | 
			
		||||
 | 
			
		||||
        if (enable_lan_discovery != 0 && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) {
 | 
			
		||||
        if (enable_lan_discovery && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) {
 | 
			
		||||
            lan_discovery_send(dht_get_net(dht), broadcast, dht_get_self_public_key(dht), net_htons_port);
 | 
			
		||||
            last_lan_discovery = mono_time_get(mono_time);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (enable_tcp_relay != 0) {
 | 
			
		||||
        if (enable_tcp_relay) {
 | 
			
		||||
            do_tcp_server(tcp_server, mono_time);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -618,7 +618,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
            log_write(LOG_LEVEL_INFO, "Received (%d) signal. Exiting.\n", caught_signal);
 | 
			
		||||
            log_write(LOG_LEVEL_INFO, "Received (%ld) signal. Exiting.\n", (long)caught_signal);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lan_discovery_kill(broadcast);
 | 
			
		||||
 
 | 
			
		||||
@@ -4,4 +4,4 @@ go 1.17
 | 
			
		||||
 | 
			
		||||
require github.com/gorilla/websocket v1.5.1
 | 
			
		||||
 | 
			
		||||
require golang.org/x/net v0.17.0 // indirect
 | 
			
		||||
require golang.org/x/net v0.23.0 // indirect
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 | 
			
		||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 | 
			
		||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
 | 
			
		||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
 | 
			
		||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 | 
			
		||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 | 
			
		||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
			
		||||
@@ -11,8 +13,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 | 
			
		||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
			
		||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 | 
			
		||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 | 
			
		||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
 | 
			
		||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 | 
			
		||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 | 
			
		||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
 | 
			
		||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
 | 
			
		||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
@@ -24,17 +28,22 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
 | 
			
		||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
			
		||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
			
		||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 | 
			
		||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 | 
			
		||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 | 
			
		||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 | 
			
		||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 | 
			
		||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 | 
			
		||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
 | 
			
		||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
			
		||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 | 
			
		||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 | 
			
		||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 | 
			
		||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 | 
			
		||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 | 
			
		||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 | 
			
		||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 | 
			
		||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 | 
			
		||||
 
 | 
			
		||||
@@ -3,10 +3,10 @@ FROM alpine:3.14.0
 | 
			
		||||
RUN ["apk", "add", "--no-cache", \
 | 
			
		||||
 "bash", \
 | 
			
		||||
 "gcc", \
 | 
			
		||||
 "linux-headers", \
 | 
			
		||||
 "musl-dev", \
 | 
			
		||||
 "libsodium-dev", \
 | 
			
		||||
 "libvpx-dev", \
 | 
			
		||||
 "linux-headers", \
 | 
			
		||||
 "musl-dev", \
 | 
			
		||||
 "opus-dev", \
 | 
			
		||||
 "perf"]
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -444,7 +444,10 @@ void generate_event_impl(const std::string& event_name, const std::vector<EventT
 | 
			
		||||
    f << "    Tox_Event event;\n";
 | 
			
		||||
    f << "    event.type = TOX_EVENT_" << str_toupper(event_name) << ";\n";
 | 
			
		||||
    f << "    event.data." << event_name_l << " = " << event_name_l << ";\n\n";
 | 
			
		||||
    f << "    tox_events_add(events, &event);\n";
 | 
			
		||||
    f << "    if (!tox_events_add(events, &event)) {\n";
 | 
			
		||||
    f << "        tox_event_" << event_name_l << "_free(" << event_name_l << ", mem);\n";
 | 
			
		||||
    f << "        return nullptr;\n";
 | 
			
		||||
    f << "    }\n";
 | 
			
		||||
    f << "    return " << event_name_l << ";\n}\n\n";
 | 
			
		||||
 | 
			
		||||
    // unpack
 | 
			
		||||
 
 | 
			
		||||
@@ -137,7 +137,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
        printf("Failed to set status. Error number: %d\n", err);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (unsigned int i = 2; i < argc; i++) { //start at 2 because that is where the tox ids are
 | 
			
		||||
    for (int i = 2; i < argc; i++) { //start at 2 because that is where the tox ids are
 | 
			
		||||
        uint8_t *address = hex_string_to_bin(argv[i]);
 | 
			
		||||
        Tox_Err_Friend_Add friend_err;
 | 
			
		||||
        tox_friend_add(tox, address, (const uint8_t *)GENERATED_REQUEST_MESSAGE, strlen(GENERATED_REQUEST_MESSAGE),
 | 
			
		||||
@@ -145,7 +145,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
        free(address);
 | 
			
		||||
 | 
			
		||||
        if (friend_err != TOX_ERR_FRIEND_ADD_OK) {
 | 
			
		||||
            printf("Failed to add friend number %u. Error number: %d\n", i - 1, friend_err);
 | 
			
		||||
            printf("Failed to add friend number %d. Error number: %d\n", i - 1, friend_err);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								external/toxcore/c-toxcore/other/fun/sign.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								external/toxcore/c-toxcore/other/fun/sign.c
									
									
									
									
										vendored
									
									
								
							@@ -35,7 +35,7 @@ static int load_file(const char *filename, unsigned char **result)
 | 
			
		||||
    fseek(f, 0, SEEK_SET);
 | 
			
		||||
    *result = (unsigned char *)malloc(size + 1);
 | 
			
		||||
 | 
			
		||||
    if (size != fread(*result, sizeof(char), size, f)) {
 | 
			
		||||
    if ((size_t)size != fread(*result, sizeof(char), size, f)) {
 | 
			
		||||
        free(*result);
 | 
			
		||||
        fclose(f);
 | 
			
		||||
        return -2; // -2 means file reading fail
 | 
			
		||||
@@ -55,13 +55,13 @@ int main(int argc, char *argv[])
 | 
			
		||||
        crypto_sign_ed25519_keypair(pk, sk);
 | 
			
		||||
        printf("Public key:\n");
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < crypto_sign_ed25519_PUBLICKEYBYTES; ++i) {
 | 
			
		||||
        for (uint32_t i = 0; i < crypto_sign_ed25519_PUBLICKEYBYTES; ++i) {
 | 
			
		||||
            printf("%02X", pk[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf("\nSecret key:\n");
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < crypto_sign_ed25519_SECRETKEYBYTES; ++i) {
 | 
			
		||||
        for (uint32_t i = 0; i < crypto_sign_ed25519_SECRETKEYBYTES; ++i) {
 | 
			
		||||
            printf("%02X", sk[i]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -117,7 +117,7 @@ int main(int argc, char *argv[])
 | 
			
		||||
#endif
 | 
			
		||||
            crypto_box_keypair(public_key, secret_key);
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i <= crypto_box_PUBLICKEYBYTES - len; ++i) {
 | 
			
		||||
            for (uint32_t i = 0; i <= crypto_box_PUBLICKEYBYTES - len; ++i) {
 | 
			
		||||
                if (memcmp(public_key + i, desired_bin, len) == 0) {
 | 
			
		||||
                    found = 1;
 | 
			
		||||
                    break;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								external/toxcore/c-toxcore/testing/Dockerfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										71
									
								
								external/toxcore/c-toxcore/testing/Dockerfile
									
									
									
									
										vendored
									
									
								
							@@ -10,22 +10,34 @@ ENV NO_ARCH_OPT 1
 | 
			
		||||
 | 
			
		||||
RUN apt-get update && \
 | 
			
		||||
    apt-get -y install --no-install-suggests --no-install-recommends \
 | 
			
		||||
    apt-transport-https \
 | 
			
		||||
    apt-utils \
 | 
			
		||||
    automake \
 | 
			
		||||
    ninja-build \
 | 
			
		||||
    bash-completion \
 | 
			
		||||
    bison flex \
 | 
			
		||||
    build-essential \
 | 
			
		||||
    git \
 | 
			
		||||
    python3 python3-dev python3-setuptools python-is-python3 \
 | 
			
		||||
    libtool libtool-bin \
 | 
			
		||||
    libglib2.0-dev \
 | 
			
		||||
    wget vim jupp nano bash-completion less \
 | 
			
		||||
    apt-utils apt-transport-https ca-certificates gnupg dialog \
 | 
			
		||||
    libpixman-1-dev \
 | 
			
		||||
    gnuplot-nox \
 | 
			
		||||
    screen \
 | 
			
		||||
    ca-certificates \
 | 
			
		||||
    cmake \
 | 
			
		||||
    parallel \
 | 
			
		||||
    dialog \
 | 
			
		||||
    git \
 | 
			
		||||
    gnupg \
 | 
			
		||||
    gnuplot-nox \
 | 
			
		||||
    jupp \
 | 
			
		||||
    less \
 | 
			
		||||
    libglib2.0-dev \
 | 
			
		||||
    libpixman-1-dev \
 | 
			
		||||
    libsodium-dev \
 | 
			
		||||
    libtool libtool-bin \
 | 
			
		||||
    nano \
 | 
			
		||||
    ninja-build \
 | 
			
		||||
    parallel \
 | 
			
		||||
    python-is-python3 \
 | 
			
		||||
    python3 \
 | 
			
		||||
    python3-dev \
 | 
			
		||||
    python3-setuptools \
 | 
			
		||||
    screen \
 | 
			
		||||
    vim \
 | 
			
		||||
    wget \
 | 
			
		||||
    && rm -rf /var/lib/apt/lists/*
 | 
			
		||||
 | 
			
		||||
RUN echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main" >> /etc/apt/sources.list && \
 | 
			
		||||
@@ -36,12 +48,37 @@ RUN echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu focal main
 | 
			
		||||
 | 
			
		||||
RUN apt-get update && apt-get full-upgrade -y && \
 | 
			
		||||
    apt-get -y install --no-install-suggests --no-install-recommends \
 | 
			
		||||
    gcc-10 g++-10 gcc-10-plugin-dev gcc-10-multilib gcc-multilib gdb lcov \
 | 
			
		||||
    clang-12 clang-tools-12 libc++1-12 libc++-12-dev \
 | 
			
		||||
    libc++abi1-12 libc++abi-12-dev libclang1-12 libclang-12-dev \
 | 
			
		||||
    libclang-common-12-dev libclang-cpp12 libclang-cpp12-dev liblld-12 \
 | 
			
		||||
    liblld-12-dev liblldb-12 liblldb-12-dev libllvm12 libomp-12-dev \
 | 
			
		||||
    libomp5-12 lld-12 lldb-12 llvm-12 llvm-12-dev llvm-12-runtime llvm-12-tools \
 | 
			
		||||
    clang-12 \
 | 
			
		||||
    clang-tools-12 \
 | 
			
		||||
    g++-10 \
 | 
			
		||||
    gcc-10 \
 | 
			
		||||
    gcc-10-multilib \
 | 
			
		||||
    gcc-10-plugin-dev \
 | 
			
		||||
    gcc-multilib \
 | 
			
		||||
    gdb \
 | 
			
		||||
    lcov \
 | 
			
		||||
    libc++-12-dev \
 | 
			
		||||
    libc++1-12 \
 | 
			
		||||
    libc++abi-12-dev \
 | 
			
		||||
    libc++abi1-12 \
 | 
			
		||||
    libclang-12-dev \
 | 
			
		||||
    libclang-common-12-dev \
 | 
			
		||||
    libclang-cpp12 \
 | 
			
		||||
    libclang-cpp12-dev \
 | 
			
		||||
    libclang1-12 \
 | 
			
		||||
    liblld-12 \
 | 
			
		||||
    liblld-12-dev \
 | 
			
		||||
    liblldb-12 \
 | 
			
		||||
    liblldb-12-dev \
 | 
			
		||||
    libllvm12 \
 | 
			
		||||
    libomp-12-dev \
 | 
			
		||||
    libomp5-12 \
 | 
			
		||||
    lld-12 \
 | 
			
		||||
    lldb-12 \
 | 
			
		||||
    llvm-12 \
 | 
			
		||||
    llvm-12-dev \
 | 
			
		||||
    llvm-12-runtime \
 | 
			
		||||
    llvm-12-tools \
 | 
			
		||||
    && rm -rf /var/lib/apt/lists/*
 | 
			
		||||
 | 
			
		||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								external/toxcore/c-toxcore/third_party/cmp
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								external/toxcore/c-toxcore/third_party/cmp
									
									
									
									
										vendored
									
									
								
							 Submodule external/toxcore/c-toxcore/third_party/cmp updated: 643e6a62d4...2ac6bca152
									
								
							
							
								
								
									
										123
									
								
								external/toxcore/c-toxcore/toxav/BUILD.bazel
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										123
									
								
								external/toxcore/c-toxcore/toxav/BUILD.bazel
									
									
									
									
										vendored
									
									
								
							@@ -42,127 +42,32 @@ cc_library(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
    name = "bwcontroller",
 | 
			
		||||
    srcs = ["bwcontroller.c"],
 | 
			
		||||
    hdrs = ["bwcontroller.h"],
 | 
			
		||||
    name = "toxav",
 | 
			
		||||
    srcs = glob(
 | 
			
		||||
        [
 | 
			
		||||
            "*.c",
 | 
			
		||||
            "*.h",
 | 
			
		||||
        ],
 | 
			
		||||
        exclude = ["toxav.h"],
 | 
			
		||||
    ),
 | 
			
		||||
    hdrs = ["toxav.h"],
 | 
			
		||||
    visibility = ["//c-toxcore:__subpackages__"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":ring_buffer",
 | 
			
		||||
        "//c-toxcore/toxcore",
 | 
			
		||||
        "//c-toxcore/toxcore:Messenger",
 | 
			
		||||
        "//c-toxcore/toxcore:ccompat",
 | 
			
		||||
        "//c-toxcore/toxcore:logger",
 | 
			
		||||
        "//c-toxcore/toxcore:mono_time",
 | 
			
		||||
        "//c-toxcore/toxcore:tox",
 | 
			
		||||
        "//c-toxcore/toxcore:util",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
    name = "rtp",
 | 
			
		||||
    srcs = ["rtp.c"],
 | 
			
		||||
    hdrs = ["rtp.h"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":bwcontroller",
 | 
			
		||||
        "//c-toxcore/toxcore:Messenger",
 | 
			
		||||
        "//c-toxcore/toxcore:ccompat",
 | 
			
		||||
        "//c-toxcore/toxcore:logger",
 | 
			
		||||
        "//c-toxcore/toxcore:mono_time",
 | 
			
		||||
        "//c-toxcore/toxcore:tox",
 | 
			
		||||
        "//c-toxcore/toxcore:util",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_test(
 | 
			
		||||
    name = "rtp_test",
 | 
			
		||||
    size = "small",
 | 
			
		||||
    srcs = ["rtp_test.cc"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":rtp",
 | 
			
		||||
        "//c-toxcore/toxcore:crypto_core",
 | 
			
		||||
        "@com_google_googletest//:gtest",
 | 
			
		||||
        "@com_google_googletest//:gtest_main",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
    name = "audio",
 | 
			
		||||
    srcs = ["audio.c"],
 | 
			
		||||
    hdrs = ["audio.h"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":public_api",
 | 
			
		||||
        ":rtp",
 | 
			
		||||
        "//c-toxcore/toxcore:ccompat",
 | 
			
		||||
        "//c-toxcore/toxcore:logger",
 | 
			
		||||
        "//c-toxcore/toxcore:mono_time",
 | 
			
		||||
        "//c-toxcore/toxcore:util",
 | 
			
		||||
        "@opus",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
    name = "video",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "msi.c",
 | 
			
		||||
        "video.c",
 | 
			
		||||
    ],
 | 
			
		||||
    hdrs = [
 | 
			
		||||
        "msi.h",
 | 
			
		||||
        "video.h",
 | 
			
		||||
    ],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":audio",
 | 
			
		||||
        ":public_api",
 | 
			
		||||
        ":ring_buffer",
 | 
			
		||||
        ":rtp",
 | 
			
		||||
        "//c-toxcore/toxcore:Messenger",
 | 
			
		||||
        "//c-toxcore/toxcore:ccompat",
 | 
			
		||||
        "//c-toxcore/toxcore:logger",
 | 
			
		||||
        "//c-toxcore/toxcore:mono_time",
 | 
			
		||||
        "//c-toxcore/toxcore:network",
 | 
			
		||||
        "//c-toxcore/toxcore:util",
 | 
			
		||||
        "@libvpx",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
    name = "groupav",
 | 
			
		||||
    srcs = ["groupav.c"],
 | 
			
		||||
    hdrs = ["groupav.h"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        "//c-toxcore/toxcore",
 | 
			
		||||
        "//c-toxcore/toxcore:ccompat",
 | 
			
		||||
        "//c-toxcore/toxcore:group",
 | 
			
		||||
        "//c-toxcore/toxcore:logger",
 | 
			
		||||
        "//c-toxcore/toxcore:mono_time",
 | 
			
		||||
        "//c-toxcore/toxcore:net_crypto",
 | 
			
		||||
        "//c-toxcore/toxcore:network",
 | 
			
		||||
        "//c-toxcore/toxcore:tox",
 | 
			
		||||
        "//c-toxcore/toxcore:util",
 | 
			
		||||
        "@libsodium",
 | 
			
		||||
        "@libvpx",
 | 
			
		||||
        "@opus",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
    name = "toxav",
 | 
			
		||||
    srcs = [
 | 
			
		||||
        "toxav.c",
 | 
			
		||||
        "toxav_old.c",
 | 
			
		||||
    ],
 | 
			
		||||
    hdrs = [
 | 
			
		||||
        "toxav.h",
 | 
			
		||||
    ],
 | 
			
		||||
    visibility = ["//c-toxcore:__subpackages__"],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":groupav",
 | 
			
		||||
        ":rtp",
 | 
			
		||||
        ":video",
 | 
			
		||||
        "//c-toxcore/toxcore:Messenger",
 | 
			
		||||
        "//c-toxcore/toxcore:ccompat",
 | 
			
		||||
        "//c-toxcore/toxcore:logger",
 | 
			
		||||
        "//c-toxcore/toxcore:mono_time",
 | 
			
		||||
        "//c-toxcore/toxcore:tox",
 | 
			
		||||
        "//c-toxcore/toxcore:util",
 | 
			
		||||
    ],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
sh_library(
 | 
			
		||||
    name = "cimple_files",
 | 
			
		||||
    srcs = glob([
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,7 @@ libtoxav_la_SOURCES = ../toxav/rtp.h \
 | 
			
		||||
                    ../toxav/ring_buffer.h \
 | 
			
		||||
                    ../toxav/ring_buffer.c \
 | 
			
		||||
                    ../toxav/toxav.h \
 | 
			
		||||
                    ../toxav/toxav_hacks.h \
 | 
			
		||||
                    ../toxav/toxav.c \
 | 
			
		||||
                    ../toxav/toxav_old.c
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										17
									
								
								external/toxcore/c-toxcore/toxav/audio.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								external/toxcore/c-toxcore/toxav/audio.c
									
									
									
									
										vendored
									
									
								
							@@ -13,6 +13,7 @@
 | 
			
		||||
#include "../toxcore/ccompat.h"
 | 
			
		||||
#include "../toxcore/logger.h"
 | 
			
		||||
#include "../toxcore/mono_time.h"
 | 
			
		||||
#include "../toxcore/network.h"
 | 
			
		||||
 | 
			
		||||
static struct JitterBuffer *jbuf_new(uint32_t capacity);
 | 
			
		||||
static void jbuf_clear(struct JitterBuffer *q);
 | 
			
		||||
@@ -25,6 +26,8 @@ static bool reconfigure_audio_encoder(const Logger *log, OpusEncoder **e, uint32
 | 
			
		||||
                                      uint8_t new_ch, uint32_t *old_br, uint32_t *old_sr, uint8_t *old_ch);
 | 
			
		||||
static bool reconfigure_audio_decoder(ACSession *ac, uint32_t sampling_rate, uint8_t channels);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ACSession *ac_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number,
 | 
			
		||||
                  toxav_audio_receive_frame_cb *cb, void *cb_data)
 | 
			
		||||
{
 | 
			
		||||
@@ -150,9 +153,9 @@ void ac_iterate(ACSession *ac)
 | 
			
		||||
 | 
			
		||||
            ac->lp_channel_count = opus_packet_get_nb_channels(msg->data + 4);
 | 
			
		||||
 | 
			
		||||
            /* NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa,
 | 
			
		||||
             * it didn't work quite well.
 | 
			
		||||
             */
 | 
			
		||||
            /** NOTE: even though OPUS supports decoding mono frames with stereo decoder and vice versa,
 | 
			
		||||
              * it didn't work quite well.
 | 
			
		||||
              */
 | 
			
		||||
            if (!reconfigure_audio_decoder(ac, ac->lp_sampling_rate, ac->lp_channel_count)) {
 | 
			
		||||
                LOGGER_WARNING(ac->log, "Failed to reconfigure decoder!");
 | 
			
		||||
                free(msg);
 | 
			
		||||
@@ -273,6 +276,7 @@ static struct JitterBuffer *jbuf_new(uint32_t capacity)
 | 
			
		||||
    q->capacity = capacity;
 | 
			
		||||
    return q;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void jbuf_clear(struct JitterBuffer *q)
 | 
			
		||||
{
 | 
			
		||||
    while (q->bottom != q->top) {
 | 
			
		||||
@@ -281,6 +285,7 @@ static void jbuf_clear(struct JitterBuffer *q)
 | 
			
		||||
        ++q->bottom;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void jbuf_free(struct JitterBuffer *q)
 | 
			
		||||
{
 | 
			
		||||
    if (q == nullptr) {
 | 
			
		||||
@@ -291,6 +296,11 @@ static void jbuf_free(struct JitterBuffer *q)
 | 
			
		||||
    free(q->queue);
 | 
			
		||||
    free(q);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * if -1 is returned the RTPMessage m needs to be free'd by the caller
 | 
			
		||||
 * if  0 is returned the RTPMessage m is stored in the ringbuffer and must NOT be freed by the caller
 | 
			
		||||
 */
 | 
			
		||||
static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessage *m)
 | 
			
		||||
{
 | 
			
		||||
    const uint16_t sequnum = m->header.sequnum;
 | 
			
		||||
@@ -319,6 +329,7 @@ static int jbuf_write(const Logger *log, struct JitterBuffer *q, struct RTPMessa
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct RTPMessage *jbuf_read(struct JitterBuffer *q, int32_t *success)
 | 
			
		||||
{
 | 
			
		||||
    if (q->top == q->bottom) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										103
									
								
								external/toxcore/c-toxcore/toxav/bwcontroller.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										103
									
								
								external/toxcore/c-toxcore/toxav/bwcontroller.c
									
									
									
									
										vendored
									
									
								
							@@ -10,12 +10,16 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "ring_buffer.h"
 | 
			
		||||
#include "toxav_hacks.h"
 | 
			
		||||
 | 
			
		||||
#include "../toxcore/ccompat.h"
 | 
			
		||||
#include "../toxcore/logger.h"
 | 
			
		||||
#include "../toxcore/mono_time.h"
 | 
			
		||||
#include "../toxcore/network.h"
 | 
			
		||||
#include "../toxcore/tox_private.h"
 | 
			
		||||
#include "../toxcore/util.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BWC_PACKET_ID 196
 | 
			
		||||
#define BWC_SEND_INTERVAL_MS 950     // 0.95s
 | 
			
		||||
#define BWC_AVG_PKT_COUNT 20
 | 
			
		||||
@@ -38,9 +42,8 @@ typedef struct BWCRcvPkt {
 | 
			
		||||
struct BWController {
 | 
			
		||||
    m_cb *mcb;
 | 
			
		||||
    void *mcb_user_data;
 | 
			
		||||
 | 
			
		||||
    Messenger *m;
 | 
			
		||||
    Tox *tox;
 | 
			
		||||
    const Logger *log;
 | 
			
		||||
    uint32_t friend_number;
 | 
			
		||||
 | 
			
		||||
    BWCCycle cycle;
 | 
			
		||||
@@ -49,6 +52,7 @@ struct BWController {
 | 
			
		||||
 | 
			
		||||
    uint32_t packet_loss_counted_cycles;
 | 
			
		||||
    Mono_Time *bwc_mono_time;
 | 
			
		||||
    bool bwc_receive_active; /* if this is set to false then incoming bwc packets will not be processed by bwc_handle_data() */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct BWCMessage {
 | 
			
		||||
@@ -56,11 +60,11 @@ struct BWCMessage {
 | 
			
		||||
    uint32_t recv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object);
 | 
			
		||||
static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length);
 | 
			
		||||
static void bwc_handle_data(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data);
 | 
			
		||||
static void send_update(BWController *bwc);
 | 
			
		||||
 | 
			
		||||
BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data,
 | 
			
		||||
 | 
			
		||||
BWController *bwc_new(const Logger *log, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data,
 | 
			
		||||
                      Mono_Time *bwc_mono_time)
 | 
			
		||||
{
 | 
			
		||||
    BWController *retu = (BWController *)calloc(1, sizeof(BWController));
 | 
			
		||||
@@ -69,16 +73,18 @@ BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb,
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(m->log, "Creating bandwidth controller");
 | 
			
		||||
    LOGGER_DEBUG(log, "Creating bandwidth controller");
 | 
			
		||||
 | 
			
		||||
    retu->mcb = mcb;
 | 
			
		||||
    retu->mcb_user_data = mcb_user_data;
 | 
			
		||||
    retu->m = m;
 | 
			
		||||
    retu->friend_number = friendnumber;
 | 
			
		||||
    retu->bwc_mono_time = bwc_mono_time;
 | 
			
		||||
    const uint64_t now = current_time_monotonic(bwc_mono_time);
 | 
			
		||||
    retu->cycle.last_sent_timestamp = now;
 | 
			
		||||
    retu->cycle.last_refresh_timestamp = now;
 | 
			
		||||
    retu->tox = tox;
 | 
			
		||||
    retu->log = log;
 | 
			
		||||
    retu->bwc_receive_active = true;
 | 
			
		||||
    retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT);
 | 
			
		||||
    retu->cycle.lost = 0;
 | 
			
		||||
    retu->cycle.recv = 0;
 | 
			
		||||
@@ -89,7 +95,6 @@ BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb,
 | 
			
		||||
        rb_write(retu->rcvpkt.rb, &retu->rcvpkt.packet_length_array[i]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_callback_rtp_packet(m, friendnumber, BWC_PACKET_ID, bwc_handle_data, retu);
 | 
			
		||||
    return retu;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -99,7 +104,6 @@ void bwc_kill(BWController *bwc)
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, nullptr, nullptr);
 | 
			
		||||
    rb_kill(bwc->rcvpkt.rb);
 | 
			
		||||
    free(bwc);
 | 
			
		||||
}
 | 
			
		||||
@@ -111,7 +115,7 @@ void bwc_add_lost(BWController *bwc, uint32_t bytes_lost)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (bytes_lost > 0) {
 | 
			
		||||
        LOGGER_DEBUG(bwc->m->log, "BWC lost(1): %d", (int)bytes_lost);
 | 
			
		||||
        LOGGER_DEBUG(bwc->log, "BWC lost(1): %d", (int)bytes_lost);
 | 
			
		||||
        bwc->cycle.lost += bytes_lost;
 | 
			
		||||
        send_update(bwc);
 | 
			
		||||
    }
 | 
			
		||||
@@ -135,7 +139,7 @@ static void send_update(BWController *bwc)
 | 
			
		||||
        bwc->packet_loss_counted_cycles = 0;
 | 
			
		||||
 | 
			
		||||
        if (bwc->cycle.lost != 0) {
 | 
			
		||||
            LOGGER_DEBUG(bwc->m->log, "%p Sent update rcv: %u lost: %u percent: %f %%",
 | 
			
		||||
            LOGGER_DEBUG(bwc->log, "%p Sent update rcv: %u lost: %u percent: %f %%",
 | 
			
		||||
                         (void *)bwc, bwc->cycle.recv, bwc->cycle.lost,
 | 
			
		||||
                         ((double)bwc->cycle.lost / (bwc->cycle.recv + bwc->cycle.lost)) * 100.0);
 | 
			
		||||
            uint8_t bwc_packet[sizeof(struct BWCMessage) + 1];
 | 
			
		||||
@@ -148,13 +152,11 @@ static void send_update(BWController *bwc)
 | 
			
		||||
            offset += net_pack_u32(bwc_packet + offset, bwc->cycle.recv);
 | 
			
		||||
            assert(offset == sizeof(bwc_packet));
 | 
			
		||||
 | 
			
		||||
            if (bwc_send_custom_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet)) == -1) {
 | 
			
		||||
                char *netstrerror = net_new_strerror(net_error());
 | 
			
		||||
                char *stdstrerror = net_new_strerror(errno);
 | 
			
		||||
                LOGGER_WARNING(bwc->m->log, "BWC send failed (len: %u)! std error: %s, net error %s",
 | 
			
		||||
                               (unsigned)sizeof(bwc_packet), stdstrerror, netstrerror);
 | 
			
		||||
                net_kill_strerror(stdstrerror);
 | 
			
		||||
                net_kill_strerror(netstrerror);
 | 
			
		||||
            Tox_Err_Friend_Custom_Packet error;
 | 
			
		||||
            tox_friend_send_lossy_packet(bwc->tox, bwc->friend_number, bwc_packet, sizeof(bwc_packet), &error);
 | 
			
		||||
 | 
			
		||||
            if (error != TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
 | 
			
		||||
                LOGGER_WARNING(bwc->log, "BWC send failed: %d", error);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -166,11 +168,11 @@ static void send_update(BWController *bwc)
 | 
			
		||||
 | 
			
		||||
static int on_update(BWController *bwc, const struct BWCMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", (void *)bwc);
 | 
			
		||||
    LOGGER_DEBUG(bwc->log, "%p Got update from peer", (void *)bwc);
 | 
			
		||||
 | 
			
		||||
    /* Peers sent update too soon */
 | 
			
		||||
    if (bwc->cycle.last_recv_timestamp + BWC_SEND_INTERVAL_MS > current_time_monotonic(bwc->bwc_mono_time)) {
 | 
			
		||||
        LOGGER_INFO(bwc->m->log, "%p Rejecting extra update", (void *)bwc);
 | 
			
		||||
        LOGGER_INFO(bwc->log, "%p Rejecting extra update", (void *)bwc);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -180,8 +182,8 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)
 | 
			
		||||
 | 
			
		||||
    if (lost != 0 && bwc->mcb != nullptr) {
 | 
			
		||||
        const uint32_t recv = msg->recv;
 | 
			
		||||
        LOGGER_DEBUG(bwc->m->log, "recved: %u lost: %u percentage: %f %%", recv, lost,
 | 
			
		||||
                     ((double)lost / (recv + lost)) * 100.0);
 | 
			
		||||
        LOGGER_DEBUG(bwc->log, "recved: %u lost: %u percentage: %f %%", recv, lost,
 | 
			
		||||
                     ((double) lost / (recv + lost)) * 100.0);
 | 
			
		||||
        bwc->mcb(bwc, bwc->friend_number,
 | 
			
		||||
                 (float)lost / (recv + lost),
 | 
			
		||||
                 bwc->mcb_user_data);
 | 
			
		||||
@@ -190,28 +192,41 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * return -1 on failure, 0 on success
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static int bwc_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length)
 | 
			
		||||
static void bwc_handle_data(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
    Tox_Err_Friend_Custom_Packet error;
 | 
			
		||||
    tox_friend_send_lossy_packet(tox, friendnumber, data, (size_t)length, &error);
 | 
			
		||||
    /* get BWController object from Tox and friend number */
 | 
			
		||||
    ToxAV *toxav = (ToxAV *)tox_get_av_object(tox);
 | 
			
		||||
 | 
			
		||||
    if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    if (toxav == nullptr) {
 | 
			
		||||
        // LOGGER_ERROR(log, "Could not get ToxAV object from Tox");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object)
 | 
			
		||||
{
 | 
			
		||||
    BWController *bwc = (BWController *)object;
 | 
			
		||||
    const Logger *log = toxav_get_logger(toxav);
 | 
			
		||||
 | 
			
		||||
    if (length - 1 != sizeof(struct BWCMessage)) {
 | 
			
		||||
        return -1;
 | 
			
		||||
        LOGGER_ERROR(log, "Got BWCMessage of insufficient size.");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const ToxAVCall *call = call_get(toxav, friend_number);
 | 
			
		||||
 | 
			
		||||
    if (call == nullptr) {
 | 
			
		||||
        LOGGER_ERROR(log, "Could not get ToxAVCall object from ToxAV.");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* get Call object from Tox and friend number */
 | 
			
		||||
    BWController *bwc = bwc_controller_get(call);
 | 
			
		||||
 | 
			
		||||
    if (bwc == nullptr) {
 | 
			
		||||
        LOGGER_WARNING(log, "No session!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!bwc->bwc_receive_active) {
 | 
			
		||||
        LOGGER_WARNING(log, "receiving not allowed!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    size_t offset = 1;  // Ignore packet id.
 | 
			
		||||
@@ -220,5 +235,15 @@ static int bwc_handle_data(Messenger *m, uint32_t friend_number, const uint8_t *
 | 
			
		||||
    offset += net_unpack_u32(data + offset, &msg.recv);
 | 
			
		||||
    assert(offset == length);
 | 
			
		||||
 | 
			
		||||
    return on_update(bwc, &msg);
 | 
			
		||||
    on_update(bwc, &msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bwc_allow_receiving(Tox *tox)
 | 
			
		||||
{
 | 
			
		||||
    tox_callback_friend_lossy_packet_per_pktid(tox, bwc_handle_data, BWC_PACKET_ID);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bwc_stop_receiving(Tox *tox)
 | 
			
		||||
{
 | 
			
		||||
    tox_callback_friend_lossy_packet_per_pktid(tox, nullptr, BWC_PACKET_ID);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								external/toxcore/c-toxcore/toxav/bwcontroller.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								external/toxcore/c-toxcore/toxav/bwcontroller.h
									
									
									
									
										vendored
									
									
								
							@@ -5,19 +5,24 @@
 | 
			
		||||
#ifndef C_TOXCORE_TOXAV_BWCONTROLLER_H
 | 
			
		||||
#define C_TOXCORE_TOXAV_BWCONTROLLER_H
 | 
			
		||||
 | 
			
		||||
#include "../toxcore/Messenger.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include "../toxcore/logger.h"
 | 
			
		||||
#include "../toxcore/mono_time.h"
 | 
			
		||||
#include "../toxcore/tox.h"
 | 
			
		||||
 | 
			
		||||
typedef struct BWController BWController;
 | 
			
		||||
 | 
			
		||||
typedef void m_cb(BWController *bwc, uint32_t friend_number, float loss, void *user_data);
 | 
			
		||||
 | 
			
		||||
BWController *bwc_new(Messenger *m, Tox *tox, uint32_t friendnumber, m_cb *mcb, void *mcb_user_data,
 | 
			
		||||
                      Mono_Time *bwc_mono_time);
 | 
			
		||||
BWController *bwc_new(const Logger *log, Tox *tox, uint32_t friendnumber,
 | 
			
		||||
                      m_cb *mcb, void *mcb_user_data, Mono_Time *bwc_mono_time);
 | 
			
		||||
 | 
			
		||||
void bwc_kill(BWController *bwc);
 | 
			
		||||
 | 
			
		||||
void bwc_add_lost(BWController *bwc, uint32_t bytes_lost);
 | 
			
		||||
void bwc_add_recv(BWController *bwc, uint32_t recv_bytes);
 | 
			
		||||
void bwc_allow_receiving(Tox *tox);
 | 
			
		||||
void bwc_stop_receiving(Tox *tox);
 | 
			
		||||
 | 
			
		||||
#endif /* C_TOXCORE_TOXAV_BWCONTROLLER_H */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								external/toxcore/c-toxcore/toxav/groupav.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								external/toxcore/c-toxcore/toxav/groupav.c
									
									
									
									
										vendored
									
									
								
							@@ -476,7 +476,7 @@ int groupchat_enable_av(const Logger *log, Tox *tox, Group_Chats *g_c, uint32_t
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < numpeers; ++i) {
 | 
			
		||||
    for (uint32_t i = 0; i < (uint32_t)numpeers; ++i) {
 | 
			
		||||
        group_av_peer_new(group_av, conference_number, i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -508,7 +508,7 @@ int groupchat_disable_av(const Group_Chats *g_c, uint32_t conference_number)
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < numpeers; ++i) {
 | 
			
		||||
    for (uint32_t i = 0; i < (uint32_t)numpeers; ++i) {
 | 
			
		||||
        group_av_peer_delete(group_av, conference_number, group_peer_get_object(g_c, conference_number, i));
 | 
			
		||||
        group_peer_set_object(g_c, conference_number, i, nullptr);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										462
									
								
								external/toxcore/c-toxcore/toxav/msi.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										462
									
								
								external/toxcore/c-toxcore/toxav/msi.c
									
									
									
									
										vendored
									
									
								
							@@ -9,8 +9,13 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "toxav_hacks.h"
 | 
			
		||||
 | 
			
		||||
#include "../toxcore/ccompat.h"
 | 
			
		||||
#include "../toxcore/logger.h"
 | 
			
		||||
#include "../toxcore/net_crypto.h"
 | 
			
		||||
#include "../toxcore/tox.h"
 | 
			
		||||
#include "../toxcore/tox_private.h"
 | 
			
		||||
#include "../toxcore/util.h"
 | 
			
		||||
 | 
			
		||||
#define MSI_MAXMSG_SIZE 256
 | 
			
		||||
@@ -55,20 +60,20 @@ typedef struct MSIMessage {
 | 
			
		||||
} MSIMessage;
 | 
			
		||||
 | 
			
		||||
static void msg_init(MSIMessage *dest, MSIRequest request);
 | 
			
		||||
static void kill_call(const Logger *log, MSICall *call);
 | 
			
		||||
static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t length);
 | 
			
		||||
static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_t *value, uint8_t value_len,
 | 
			
		||||
                                     uint16_t *length);
 | 
			
		||||
static int send_message(const Messenger *m, uint32_t friend_number, const MSIMessage *msg);
 | 
			
		||||
static int send_error(const Messenger *m, uint32_t friend_number, MSIError error);
 | 
			
		||||
static bool invoke_callback(MSICall *call, MSICallbackID cb);
 | 
			
		||||
static int send_message(const Logger *log, Tox *tox, uint32_t friend_number, const MSIMessage *msg);
 | 
			
		||||
static int send_error(const Logger *log, Tox *tox, uint32_t friend_number, MSIError error);
 | 
			
		||||
static MSICall *get_call(MSISession *session, uint32_t friend_number);
 | 
			
		||||
static MSICall *new_call(MSISession *session, uint32_t friend_number);
 | 
			
		||||
static void kill_call(MSICall *call);
 | 
			
		||||
static void on_peer_status(Messenger *m, uint32_t friend_number, bool is_online, void *user_data);
 | 
			
		||||
static void handle_init(MSICall *call, const MSIMessage *msg);
 | 
			
		||||
static void handle_push(MSICall *call, const MSIMessage *msg);
 | 
			
		||||
static void handle_pop(MSICall *call, const MSIMessage *msg);
 | 
			
		||||
static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *user_data);
 | 
			
		||||
static bool invoke_callback(const Logger *log, MSICall *call, MSICallbackID cb);
 | 
			
		||||
static void handle_init(const Logger *log, MSICall *call, const MSIMessage *msg);
 | 
			
		||||
static void handle_push(const Logger *log, MSICall *call, const MSIMessage *msg);
 | 
			
		||||
static void handle_pop(const Logger *log, MSICall *call, const MSIMessage *msg);
 | 
			
		||||
static void handle_msi_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
 | 
			
		||||
                              void *user_data);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Public functions
 | 
			
		||||
@@ -99,43 +104,43 @@ void msi_callback_capabilities(MSISession *session, msi_action_cb *callback)
 | 
			
		||||
    session->capabilities_callback = callback;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MSISession *msi_new(Messenger *m)
 | 
			
		||||
MSISession *msi_new(const Logger *log, Tox *tox)
 | 
			
		||||
{
 | 
			
		||||
    if (m == nullptr) {
 | 
			
		||||
    if (tox == nullptr) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MSISession *retu = (MSISession *)calloc(1, sizeof(MSISession));
 | 
			
		||||
 | 
			
		||||
    if (retu == nullptr) {
 | 
			
		||||
        LOGGER_ERROR(m->log, "Allocation failed! Program might misbehave!");
 | 
			
		||||
        LOGGER_ERROR(log, "Allocation failed! Program might misbehave!");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (create_recursive_mutex(retu->mutex) != 0) {
 | 
			
		||||
        LOGGER_ERROR(m->log, "Failed to init mutex! Program might misbehave");
 | 
			
		||||
        LOGGER_ERROR(log, "Failed to init mutex! Program might misbehave");
 | 
			
		||||
        free(retu);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    retu->messenger = m;
 | 
			
		||||
    retu->tox = tox;
 | 
			
		||||
 | 
			
		||||
    m_callback_msi_packet(m, handle_msi_packet, retu);
 | 
			
		||||
    // register callback
 | 
			
		||||
    tox_callback_friend_lossless_packet_per_pktid(tox, handle_msi_packet, PACKET_ID_MSI);
 | 
			
		||||
 | 
			
		||||
    /* This is called when remote terminates session */
 | 
			
		||||
    m_callback_connectionstatus_internal_av(m, on_peer_status, retu);
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(m->log, "New msi session: %p ", (void *)retu);
 | 
			
		||||
    LOGGER_DEBUG(log, "New msi session: %p ", (void *)retu);
 | 
			
		||||
    return retu;
 | 
			
		||||
}
 | 
			
		||||
int msi_kill(MSISession *session, const Logger *log)
 | 
			
		||||
 | 
			
		||||
int msi_kill(const Logger *log, Tox *tox, MSISession *session)
 | 
			
		||||
{
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        LOGGER_ERROR(log, "Tried to terminate non-existing session");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_callback_msi_packet(session->messenger, nullptr, nullptr);
 | 
			
		||||
    // UN-register callback
 | 
			
		||||
    tox_callback_friend_lossless_packet_per_pktid(tox, nullptr, PACKET_ID_MSI);
 | 
			
		||||
 | 
			
		||||
    if (pthread_mutex_trylock(session->mutex) != 0) {
 | 
			
		||||
        LOGGER_ERROR(log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
@@ -149,10 +154,10 @@ int msi_kill(MSISession *session, const Logger *log)
 | 
			
		||||
        MSICall *it = get_call(session, session->calls_head);
 | 
			
		||||
 | 
			
		||||
        while (it != nullptr) {
 | 
			
		||||
            send_message(session->messenger, it->friend_number, &msg);
 | 
			
		||||
            send_message(log, session->tox, it->friend_number, &msg);
 | 
			
		||||
            MSICall *temp_it = it;
 | 
			
		||||
            it = it->next;
 | 
			
		||||
            kill_call(temp_it); /* This will eventually free session->calls */
 | 
			
		||||
            kill_call(log, temp_it); /* This will eventually free session->calls */
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -163,21 +168,57 @@ int msi_kill(MSISession *session, const Logger *log)
 | 
			
		||||
    free(session);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities)
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * return true if friend is offline and the call was canceled.
 | 
			
		||||
 */
 | 
			
		||||
bool check_peer_offline_status(const Logger *log, const Tox *tox, MSISession *session, uint32_t friend_number)
 | 
			
		||||
{
 | 
			
		||||
    if (tox == nullptr || session == nullptr) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Tox_Err_Friend_Query f_con_query_error;
 | 
			
		||||
    const Tox_Connection f_con_status = tox_friend_get_connection_status(tox, friend_number, &f_con_query_error);
 | 
			
		||||
 | 
			
		||||
    if (f_con_status == TOX_CONNECTION_NONE) {
 | 
			
		||||
        /* Friend is now offline */
 | 
			
		||||
        LOGGER_DEBUG(log, "Friend %d is now offline", friend_number);
 | 
			
		||||
 | 
			
		||||
        pthread_mutex_lock(session->mutex);
 | 
			
		||||
        MSICall *call = get_call(session, friend_number);
 | 
			
		||||
 | 
			
		||||
        if (call == nullptr) {
 | 
			
		||||
            pthread_mutex_unlock(session->mutex);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        invoke_callback(log, call, MSI_ON_PEERTIMEOUT); /* Failure is ignored */
 | 
			
		||||
        kill_call(log, call);
 | 
			
		||||
        pthread_mutex_unlock(session->mutex);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int msi_invite(const Logger *log, MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities)
 | 
			
		||||
{
 | 
			
		||||
    LOGGER_DEBUG(log, "msi_invite:session:%p", (void *)session);
 | 
			
		||||
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->messenger->log, "Session: %p Inviting friend: %u", (void *)session, friend_number);
 | 
			
		||||
    LOGGER_DEBUG(log, "Session: %p Inviting friend: %u", (void *)session, friend_number);
 | 
			
		||||
 | 
			
		||||
    if (pthread_mutex_trylock(session->mutex) != 0) {
 | 
			
		||||
        LOGGER_ERROR(session->messenger->log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
        LOGGER_ERROR(log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (get_call(session, friend_number) != nullptr) {
 | 
			
		||||
        LOGGER_ERROR(session->messenger->log, "Already in a call");
 | 
			
		||||
        LOGGER_ERROR(log, "Already in a call");
 | 
			
		||||
        pthread_mutex_unlock(session->mutex);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -197,17 +238,18 @@ int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint
 | 
			
		||||
    msg.capabilities.exists = true;
 | 
			
		||||
    msg.capabilities.value = capabilities;
 | 
			
		||||
 | 
			
		||||
    send_message(temp->session->messenger, temp->friend_number, &msg);
 | 
			
		||||
    send_message(log, temp->session->tox, temp->friend_number, &msg);
 | 
			
		||||
 | 
			
		||||
    temp->state = MSI_CALL_REQUESTING;
 | 
			
		||||
 | 
			
		||||
    *call = temp;
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->messenger->log, "Invite sent");
 | 
			
		||||
    LOGGER_DEBUG(log, "Invite sent");
 | 
			
		||||
    pthread_mutex_unlock(session->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
int msi_hangup(MSICall *call)
 | 
			
		||||
 | 
			
		||||
int msi_hangup(const Logger *log, MSICall *call)
 | 
			
		||||
{
 | 
			
		||||
    if (call == nullptr || call->session == nullptr) {
 | 
			
		||||
        return -1;
 | 
			
		||||
@@ -215,16 +257,16 @@ int msi_hangup(MSICall *call)
 | 
			
		||||
 | 
			
		||||
    MSISession *session = call->session;
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->messenger->log, "Session: %p Hanging up call with friend: %u", (void *)call->session,
 | 
			
		||||
    LOGGER_DEBUG(log, "Session: %p Hanging up call with friend: %u", (void *)call->session,
 | 
			
		||||
                 call->friend_number);
 | 
			
		||||
 | 
			
		||||
    if (pthread_mutex_trylock(session->mutex) != 0) {
 | 
			
		||||
        LOGGER_ERROR(session->messenger->log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
        LOGGER_ERROR(log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (call->state == MSI_CALL_INACTIVE) {
 | 
			
		||||
        LOGGER_ERROR(session->messenger->log, "Call is in invalid state!");
 | 
			
		||||
        LOGGER_ERROR(log, "Call is in invalid state!");
 | 
			
		||||
        pthread_mutex_unlock(session->mutex);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -232,13 +274,14 @@ int msi_hangup(MSICall *call)
 | 
			
		||||
    MSIMessage msg;
 | 
			
		||||
    msg_init(&msg, REQU_POP);
 | 
			
		||||
 | 
			
		||||
    send_message(session->messenger, call->friend_number, &msg);
 | 
			
		||||
    send_message(log, session->tox, call->friend_number, &msg);
 | 
			
		||||
 | 
			
		||||
    kill_call(call);
 | 
			
		||||
    kill_call(log, call);
 | 
			
		||||
    pthread_mutex_unlock(session->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
int msi_answer(MSICall *call, uint8_t capabilities)
 | 
			
		||||
 | 
			
		||||
int msi_answer(const Logger *log, MSICall *call, uint8_t capabilities)
 | 
			
		||||
{
 | 
			
		||||
    if (call == nullptr || call->session == nullptr) {
 | 
			
		||||
        return -1;
 | 
			
		||||
@@ -246,18 +289,18 @@ int msi_answer(MSICall *call, uint8_t capabilities)
 | 
			
		||||
 | 
			
		||||
    MSISession *session = call->session;
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->messenger->log, "Session: %p Answering call from: %u", (void *)call->session,
 | 
			
		||||
    LOGGER_DEBUG(log, "Session: %p Answering call from: %u", (void *)call->session,
 | 
			
		||||
                 call->friend_number);
 | 
			
		||||
 | 
			
		||||
    if (pthread_mutex_trylock(session->mutex) != 0) {
 | 
			
		||||
        LOGGER_ERROR(session->messenger->log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
        LOGGER_ERROR(log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (call->state != MSI_CALL_REQUESTED) {
 | 
			
		||||
        /* Though sending in invalid state will not cause anything weird
 | 
			
		||||
         * Its better to not do it like a maniac */
 | 
			
		||||
        LOGGER_ERROR(session->messenger->log, "Call is in invalid state!");
 | 
			
		||||
        LOGGER_ERROR(log, "Call is in invalid state!");
 | 
			
		||||
        pthread_mutex_unlock(session->mutex);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -270,14 +313,15 @@ int msi_answer(MSICall *call, uint8_t capabilities)
 | 
			
		||||
    msg.capabilities.exists = true;
 | 
			
		||||
    msg.capabilities.value = capabilities;
 | 
			
		||||
 | 
			
		||||
    send_message(session->messenger, call->friend_number, &msg);
 | 
			
		||||
    send_message(log, session->tox, call->friend_number, &msg);
 | 
			
		||||
 | 
			
		||||
    call->state = MSI_CALL_ACTIVE;
 | 
			
		||||
    pthread_mutex_unlock(session->mutex);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
int msi_change_capabilities(MSICall *call, uint8_t capabilities)
 | 
			
		||||
 | 
			
		||||
int msi_change_capabilities(const Logger *log, MSICall *call, uint8_t capabilities)
 | 
			
		||||
{
 | 
			
		||||
    if (call == nullptr || call->session == nullptr) {
 | 
			
		||||
        return -1;
 | 
			
		||||
@@ -285,16 +329,16 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities)
 | 
			
		||||
 | 
			
		||||
    MSISession *session = call->session;
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->messenger->log, "Session: %p Trying to change capabilities to friend %u", (void *)call->session,
 | 
			
		||||
    LOGGER_DEBUG(log, "Session: %p Trying to change capabilities to friend %u", (void *)call->session,
 | 
			
		||||
                 call->friend_number);
 | 
			
		||||
 | 
			
		||||
    if (pthread_mutex_trylock(session->mutex) != 0) {
 | 
			
		||||
        LOGGER_ERROR(session->messenger->log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
        LOGGER_ERROR(log, "Failed to acquire lock on msi mutex");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (call->state != MSI_CALL_ACTIVE) {
 | 
			
		||||
        LOGGER_ERROR(session->messenger->log, "Call is in invalid state!");
 | 
			
		||||
        LOGGER_ERROR(log, "Call is in invalid state!");
 | 
			
		||||
        pthread_mutex_unlock(session->mutex);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -307,7 +351,7 @@ int msi_change_capabilities(MSICall *call, uint8_t capabilities)
 | 
			
		||||
    msg.capabilities.exists = true;
 | 
			
		||||
    msg.capabilities.value = capabilities;
 | 
			
		||||
 | 
			
		||||
    send_message(call->session->messenger, call->friend_number, &msg);
 | 
			
		||||
    send_message(log, call->session->tox, call->friend_number, &msg);
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(session->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
@@ -351,10 +395,51 @@ static bool check_enum_high(const Logger *log, const uint8_t *bytes, uint8_t enu
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const uint8_t *msg_parse_one(const Logger *log, MSIMessage *dest, const uint8_t *it, int *size_constraint)
 | 
			
		||||
{
 | 
			
		||||
    switch (*it) {
 | 
			
		||||
        case ID_REQUEST: {
 | 
			
		||||
            if (!check_size(log, it, size_constraint, 1) ||
 | 
			
		||||
                    !check_enum_high(log, it, REQU_POP)) {
 | 
			
		||||
                return nullptr;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            dest->request.value = (MSIRequest)it[2];
 | 
			
		||||
            dest->request.exists = true;
 | 
			
		||||
            return it + 3;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case ID_ERROR: {
 | 
			
		||||
            if (!check_size(log, it, size_constraint, 1) ||
 | 
			
		||||
                    !check_enum_high(log, it, MSI_E_UNDISCLOSED)) {
 | 
			
		||||
                return nullptr;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            dest->error.value = (MSIError)it[2];
 | 
			
		||||
            dest->error.exists = true;
 | 
			
		||||
            return it + 3;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case ID_CAPABILITIES: {
 | 
			
		||||
            if (!check_size(log, it, size_constraint, 1)) {
 | 
			
		||||
                return nullptr;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            dest->capabilities.value = it[2];
 | 
			
		||||
            dest->capabilities.exists = true;
 | 
			
		||||
            return it + 3;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default: {
 | 
			
		||||
            LOGGER_ERROR(log, "Invalid id byte: %d", *it);
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t length)
 | 
			
		||||
{
 | 
			
		||||
    /* Parse raw data received from socket into MSIMessage struct */
 | 
			
		||||
 | 
			
		||||
    assert(dest != nullptr);
 | 
			
		||||
 | 
			
		||||
    if (length == 0 || data[length - 1] != 0) { /* End byte must have value 0 */
 | 
			
		||||
@@ -368,46 +453,10 @@ static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data
 | 
			
		||||
    int size_constraint = length;
 | 
			
		||||
 | 
			
		||||
    while (*it != 0) {/* until end byte is hit */
 | 
			
		||||
        switch (*it) {
 | 
			
		||||
            case ID_REQUEST: {
 | 
			
		||||
                if (!check_size(log, it, &size_constraint, 1) ||
 | 
			
		||||
                        !check_enum_high(log, it, REQU_POP)) {
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
        it = msg_parse_one(log, dest, it, &size_constraint);
 | 
			
		||||
 | 
			
		||||
                dest->request.value = (MSIRequest)it[2];
 | 
			
		||||
                dest->request.exists = true;
 | 
			
		||||
                it += 3;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case ID_ERROR: {
 | 
			
		||||
                if (!check_size(log, it, &size_constraint, 1) ||
 | 
			
		||||
                        !check_enum_high(log, it, MSI_E_UNDISCLOSED)) {
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                dest->error.value = (MSIError)it[2];
 | 
			
		||||
                dest->error.exists = true;
 | 
			
		||||
                it += 3;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case ID_CAPABILITIES: {
 | 
			
		||||
                if (!check_size(log, it, &size_constraint, 1)) {
 | 
			
		||||
                    return -1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                dest->capabilities.value = it[2];
 | 
			
		||||
                dest->capabilities.exists = true;
 | 
			
		||||
                it += 3;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            default: {
 | 
			
		||||
                LOGGER_ERROR(log, "Invalid id byte");
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        if (it == nullptr) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -418,6 +467,7 @@ static int msg_parse_in(const Logger *log, MSIMessage *dest, const uint8_t *data
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_t *value, uint8_t value_len,
 | 
			
		||||
                                     uint16_t *length)
 | 
			
		||||
{
 | 
			
		||||
@@ -437,11 +487,48 @@ static uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const uint8_
 | 
			
		||||
 | 
			
		||||
    return dest + value_len; /* Set to next position ready to be written */
 | 
			
		||||
}
 | 
			
		||||
static int send_message(const Messenger *m, uint32_t friend_number, const MSIMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    /* Parse and send message */
 | 
			
		||||
    assert(m != nullptr);
 | 
			
		||||
 | 
			
		||||
/* Send an msi packet.
 | 
			
		||||
 *
 | 
			
		||||
 *  return 1 on success
 | 
			
		||||
 *  return 0 on failure
 | 
			
		||||
 */
 | 
			
		||||
static int m_msi_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint16_t length)
 | 
			
		||||
{
 | 
			
		||||
    // TODO(Zoff): make this better later! -------------------
 | 
			
		||||
    /* we need to prepend 1 byte (packet id) to data
 | 
			
		||||
     * do this without malloc, memcpy and free in the future
 | 
			
		||||
     */
 | 
			
		||||
    const size_t length_new = (size_t)length + 1;
 | 
			
		||||
    uint8_t *data_new = (uint8_t *)malloc(length_new);
 | 
			
		||||
 | 
			
		||||
    if (data_new == nullptr) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    data_new[0] = PACKET_ID_MSI;
 | 
			
		||||
 | 
			
		||||
    if (length != 0) {
 | 
			
		||||
        memcpy(data_new + 1, data, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Tox_Err_Friend_Custom_Packet error;
 | 
			
		||||
    tox_friend_send_lossless_packet(tox, friendnumber, data_new, length_new, &error);
 | 
			
		||||
 | 
			
		||||
    free(data_new);
 | 
			
		||||
 | 
			
		||||
    if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int send_message(const Logger *log, Tox *tox, uint32_t friend_number, const MSIMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    assert(tox != nullptr);
 | 
			
		||||
 | 
			
		||||
    /* Parse and send message */
 | 
			
		||||
    uint8_t parsed[MSI_MAXMSG_SIZE];
 | 
			
		||||
 | 
			
		||||
    uint8_t *it = parsed;
 | 
			
		||||
@@ -452,7 +539,7 @@ static int send_message(const Messenger *m, uint32_t friend_number, const MSIMes
 | 
			
		||||
        it = msg_parse_header_out(ID_REQUEST, it, &cast,
 | 
			
		||||
                                  sizeof(cast), &size);
 | 
			
		||||
    } else {
 | 
			
		||||
        LOGGER_DEBUG(m->log, "Must have request field");
 | 
			
		||||
        LOGGER_DEBUG(log, "Must have request field");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -468,26 +555,27 @@ static int send_message(const Messenger *m, uint32_t friend_number, const MSIMes
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (it == parsed) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "Parsing message failed; empty message");
 | 
			
		||||
        LOGGER_WARNING(log, "Parsing message failed; empty message");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    *it = 0;
 | 
			
		||||
    ++size;
 | 
			
		||||
 | 
			
		||||
    if (m_msi_packet(m, friend_number, parsed, size)) {
 | 
			
		||||
        LOGGER_DEBUG(m->log, "Sent message");
 | 
			
		||||
    if (m_msi_packet(tox, friend_number, parsed, size) == 1) {
 | 
			
		||||
        LOGGER_DEBUG(log, "Sent message");
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
static int send_error(const Messenger *m, uint32_t friend_number, MSIError error)
 | 
			
		||||
{
 | 
			
		||||
    /* Send error message */
 | 
			
		||||
    assert(m != nullptr);
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(m->log, "Sending error: %d to friend: %d", error, friend_number);
 | 
			
		||||
static int send_error(const Logger *log, Tox *tox, uint32_t friend_number, MSIError error)
 | 
			
		||||
{
 | 
			
		||||
    assert(tox != nullptr);
 | 
			
		||||
 | 
			
		||||
    /* Send error message */
 | 
			
		||||
    LOGGER_DEBUG(log, "Sending error: %d to friend: %d", error, friend_number);
 | 
			
		||||
 | 
			
		||||
    MSIMessage msg;
 | 
			
		||||
    msg_init(&msg, REQU_POP);
 | 
			
		||||
@@ -495,13 +583,14 @@ static int send_error(const Messenger *m, uint32_t friend_number, MSIError error
 | 
			
		||||
    msg.error.exists = true;
 | 
			
		||||
    msg.error.value = error;
 | 
			
		||||
 | 
			
		||||
    send_message(m, friend_number, &msg);
 | 
			
		||||
    send_message(log, tox, friend_number, &msg);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
static int invoke_callback_inner(MSICall *call, MSICallbackID id)
 | 
			
		||||
 | 
			
		||||
static int invoke_callback_inner(const Logger *log, MSICall *call, MSICallbackID id)
 | 
			
		||||
{
 | 
			
		||||
    MSISession *session = call->session;
 | 
			
		||||
    LOGGER_DEBUG(session->messenger->log, "invoking callback function: %d", id);
 | 
			
		||||
    LOGGER_DEBUG(log, "invoking callback function: %d", id);
 | 
			
		||||
 | 
			
		||||
    switch (id) {
 | 
			
		||||
        case MSI_ON_INVITE:
 | 
			
		||||
@@ -523,15 +612,16 @@ static int invoke_callback_inner(MSICall *call, MSICallbackID id)
 | 
			
		||||
            return session->capabilities_callback(session->av, call);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_FATAL(session->messenger->log, "invalid callback id: %d", id);
 | 
			
		||||
    LOGGER_FATAL(log, "invalid callback id: %d", id);
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
static bool invoke_callback(MSICall *call, MSICallbackID cb)
 | 
			
		||||
 | 
			
		||||
static bool invoke_callback(const Logger *log, MSICall *call, MSICallbackID cb)
 | 
			
		||||
{
 | 
			
		||||
    assert(call != nullptr);
 | 
			
		||||
 | 
			
		||||
    if (invoke_callback_inner(call, cb) != 0) {
 | 
			
		||||
        LOGGER_WARNING(call->session->messenger->log,
 | 
			
		||||
    if (invoke_callback_inner(log, call, cb) != 0) {
 | 
			
		||||
        LOGGER_WARNING(log,
 | 
			
		||||
                       "Callback state handling failed, sending error");
 | 
			
		||||
 | 
			
		||||
        /* If no callback present or error happened while handling,
 | 
			
		||||
@@ -546,6 +636,7 @@ static bool invoke_callback(MSICall *call, MSICallbackID cb)
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MSICall *get_call(MSISession *session, uint32_t friend_number)
 | 
			
		||||
{
 | 
			
		||||
    assert(session != nullptr);
 | 
			
		||||
@@ -556,6 +647,7 @@ static MSICall *get_call(MSISession *session, uint32_t friend_number)
 | 
			
		||||
 | 
			
		||||
    return session->calls[friend_number];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static MSICall *new_call(MSISession *session, uint32_t friend_number)
 | 
			
		||||
{
 | 
			
		||||
    assert(session != nullptr);
 | 
			
		||||
@@ -607,7 +699,8 @@ static MSICall *new_call(MSISession *session, uint32_t friend_number)
 | 
			
		||||
    session->calls[friend_number] = rc;
 | 
			
		||||
    return rc;
 | 
			
		||||
}
 | 
			
		||||
static void kill_call(MSICall *call)
 | 
			
		||||
 | 
			
		||||
static void kill_call(const Logger *log, MSICall *call)
 | 
			
		||||
{
 | 
			
		||||
    /* Assume that session mutex is locked */
 | 
			
		||||
    if (call == nullptr) {
 | 
			
		||||
@@ -616,7 +709,7 @@ static void kill_call(MSICall *call)
 | 
			
		||||
 | 
			
		||||
    MSISession *session = call->session;
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->messenger->log, "Killing call: %p", (void *)call);
 | 
			
		||||
    LOGGER_DEBUG(log, "Killing call: %p", (void *)call);
 | 
			
		||||
 | 
			
		||||
    MSICall *prev = call->prev;
 | 
			
		||||
    MSICall *next = call->next;
 | 
			
		||||
@@ -648,37 +741,12 @@ CLEAR_CONTAINER:
 | 
			
		||||
    free(call);
 | 
			
		||||
    session->calls = nullptr;
 | 
			
		||||
}
 | 
			
		||||
static void on_peer_status(Messenger *m, uint32_t friend_number, bool is_online, void *user_data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool try_handle_init(const Logger *log, MSICall *call, const MSIMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    MSISession *session = (MSISession *)user_data;
 | 
			
		||||
 | 
			
		||||
    if (is_online) {
 | 
			
		||||
        // Friend is online.
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(m->log, "Friend %d is now offline", friend_number);
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(session->mutex);
 | 
			
		||||
    MSICall *call = get_call(session, friend_number);
 | 
			
		||||
 | 
			
		||||
    if (call == nullptr) {
 | 
			
		||||
        pthread_mutex_unlock(session->mutex);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    invoke_callback(call, MSI_ON_PEERTIMEOUT); /* Failure is ignored */
 | 
			
		||||
    kill_call(call);
 | 
			
		||||
    pthread_mutex_unlock(session->mutex);
 | 
			
		||||
}
 | 
			
		||||
static bool try_handle_init(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    assert(call != nullptr);
 | 
			
		||||
    LOGGER_DEBUG(call->session->messenger->log,
 | 
			
		||||
                 "Session: %p Handling 'init' friend: %d", (void *)call->session, call->friend_number);
 | 
			
		||||
 | 
			
		||||
    if (!msg->capabilities.exists) {
 | 
			
		||||
        LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'init'", (void *)call->session);
 | 
			
		||||
        LOGGER_WARNING(log, "Session: %p Invalid capabilities on 'init'", (void *)call->session);
 | 
			
		||||
        call->error = MSI_E_INVALID_MESSAGE;
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
@@ -689,7 +757,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
            call->peer_capabilities = msg->capabilities.value;
 | 
			
		||||
            call->state = MSI_CALL_REQUESTED;
 | 
			
		||||
 | 
			
		||||
            if (!invoke_callback(call, MSI_ON_INVITE)) {
 | 
			
		||||
            if (!invoke_callback(log, call, MSI_ON_INVITE)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -704,7 +772,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
             * we can automatically answer the re-call.
 | 
			
		||||
             */
 | 
			
		||||
 | 
			
		||||
            LOGGER_INFO(call->session->messenger->log, "Friend is recalling us");
 | 
			
		||||
            LOGGER_INFO(log, "Friend is recalling us");
 | 
			
		||||
 | 
			
		||||
            MSIMessage out_msg;
 | 
			
		||||
            msg_init(&out_msg, REQU_PUSH);
 | 
			
		||||
@@ -712,7 +780,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
            out_msg.capabilities.exists = true;
 | 
			
		||||
            out_msg.capabilities.value = call->self_capabilities;
 | 
			
		||||
 | 
			
		||||
            send_message(call->session->messenger, call->friend_number, &out_msg);
 | 
			
		||||
            send_message(log, call->session->tox, call->friend_number, &out_msg);
 | 
			
		||||
 | 
			
		||||
            /* If peer changed capabilities during re-call they will
 | 
			
		||||
             * be handled accordingly during the next step
 | 
			
		||||
@@ -722,7 +790,7 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
 | 
			
		||||
        case MSI_CALL_REQUESTED: // fall-through
 | 
			
		||||
        case MSI_CALL_REQUESTING: {
 | 
			
		||||
            LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid state on 'init'", (void *)call->session);
 | 
			
		||||
            LOGGER_WARNING(log, "Session: %p Invalid state on 'init'", (void *)call->session);
 | 
			
		||||
            call->error = MSI_E_INVALID_STATE;
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -730,26 +798,28 @@ static bool try_handle_init(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
static void handle_init(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
 | 
			
		||||
static void handle_init(const Logger *log, MSICall *call, const MSIMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    assert(call != nullptr);
 | 
			
		||||
    LOGGER_DEBUG(call->session->messenger->log,
 | 
			
		||||
    LOGGER_DEBUG(log,
 | 
			
		||||
                 "Session: %p Handling 'init' friend: %d", (void *)call->session, call->friend_number);
 | 
			
		||||
 | 
			
		||||
    if (!try_handle_init(call, msg)) {
 | 
			
		||||
        send_error(call->session->messenger, call->friend_number, call->error);
 | 
			
		||||
        kill_call(call);
 | 
			
		||||
    if (!try_handle_init(log, call, msg)) {
 | 
			
		||||
        send_error(log, call->session->tox, call->friend_number, call->error);
 | 
			
		||||
        kill_call(log, call);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
static void handle_push(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
 | 
			
		||||
static void handle_push(const Logger *log, MSICall *call, const MSIMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    assert(call != nullptr);
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(call->session->messenger->log, "Session: %p Handling 'push' friend: %d", (void *)call->session,
 | 
			
		||||
    LOGGER_DEBUG(log, "Session: %p Handling 'push' friend: %d", (void *)call->session,
 | 
			
		||||
                 call->friend_number);
 | 
			
		||||
 | 
			
		||||
    if (!msg->capabilities.exists) {
 | 
			
		||||
        LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'push'", (void *)call->session);
 | 
			
		||||
        LOGGER_WARNING(log, "Session: %p Invalid capabilities on 'push'", (void *)call->session);
 | 
			
		||||
        call->error = MSI_E_INVALID_MESSAGE;
 | 
			
		||||
        goto FAILURE;
 | 
			
		||||
    }
 | 
			
		||||
@@ -757,12 +827,11 @@ static void handle_push(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
    switch (call->state) {
 | 
			
		||||
        case MSI_CALL_ACTIVE: {
 | 
			
		||||
            if (call->peer_capabilities != msg->capabilities.value) {
 | 
			
		||||
                /* Only act if capabilities changed */
 | 
			
		||||
                LOGGER_INFO(call->session->messenger->log, "Friend is changing capabilities to: %u", msg->capabilities.value);
 | 
			
		||||
                LOGGER_INFO(log, "Friend is changing capabilities to: %u", msg->capabilities.value);
 | 
			
		||||
 | 
			
		||||
                call->peer_capabilities = msg->capabilities.value;
 | 
			
		||||
 | 
			
		||||
                if (!invoke_callback(call, MSI_ON_CAPABILITIES)) {
 | 
			
		||||
                if (!invoke_callback(log, call, MSI_ON_CAPABILITIES)) {
 | 
			
		||||
                    goto FAILURE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -771,13 +840,13 @@ static void handle_push(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case MSI_CALL_REQUESTING: {
 | 
			
		||||
            LOGGER_INFO(call->session->messenger->log, "Friend answered our call");
 | 
			
		||||
            LOGGER_INFO(log, "Friend answered our call");
 | 
			
		||||
 | 
			
		||||
            /* Call started */
 | 
			
		||||
            call->peer_capabilities = msg->capabilities.value;
 | 
			
		||||
            call->state = MSI_CALL_ACTIVE;
 | 
			
		||||
 | 
			
		||||
            if (!invoke_callback(call, MSI_ON_START)) {
 | 
			
		||||
            if (!invoke_callback(log, call, MSI_ON_START)) {
 | 
			
		||||
                goto FAILURE;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -786,8 +855,7 @@ static void handle_push(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
 | 
			
		||||
        case MSI_CALL_INACTIVE: // fall-through
 | 
			
		||||
        case MSI_CALL_REQUESTED: {
 | 
			
		||||
            /* Pushes during initialization state are ignored */
 | 
			
		||||
            LOGGER_WARNING(call->session->messenger->log, "Ignoring invalid push");
 | 
			
		||||
            LOGGER_WARNING(log, "Ignoring invalid push");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -795,76 +863,102 @@ static void handle_push(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
FAILURE:
 | 
			
		||||
    send_error(call->session->messenger, call->friend_number, call->error);
 | 
			
		||||
    kill_call(call);
 | 
			
		||||
    send_error(log, call->session->tox, call->friend_number, call->error);
 | 
			
		||||
    kill_call(log, call);
 | 
			
		||||
}
 | 
			
		||||
static void handle_pop(MSICall *call, const MSIMessage *msg)
 | 
			
		||||
 | 
			
		||||
static void handle_pop(const Logger *log, MSICall *call, const MSIMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    assert(call != nullptr);
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(call->session->messenger->log, "Session: %p Handling 'pop', friend id: %d", (void *)call->session,
 | 
			
		||||
    LOGGER_DEBUG(log, "Session: %p Handling 'pop', friend id: %d", (void *)call->session,
 | 
			
		||||
                 call->friend_number);
 | 
			
		||||
 | 
			
		||||
    /* callback errors are ignored */
 | 
			
		||||
 | 
			
		||||
    if (msg->error.exists) {
 | 
			
		||||
        LOGGER_WARNING(call->session->messenger->log, "Friend detected an error: %d", msg->error.value);
 | 
			
		||||
        LOGGER_WARNING(log, "Friend detected an error: %d", msg->error.value);
 | 
			
		||||
        call->error = msg->error.value;
 | 
			
		||||
        invoke_callback(call, MSI_ON_ERROR);
 | 
			
		||||
        invoke_callback(log, call, MSI_ON_ERROR);
 | 
			
		||||
    } else {
 | 
			
		||||
        switch (call->state) {
 | 
			
		||||
            case MSI_CALL_INACTIVE: {
 | 
			
		||||
                LOGGER_FATAL(call->session->messenger->log, "Handling what should be impossible case");
 | 
			
		||||
                LOGGER_FATAL(log, "Handling what should be impossible case");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case MSI_CALL_ACTIVE: {
 | 
			
		||||
                /* Hangup */
 | 
			
		||||
                LOGGER_INFO(call->session->messenger->log, "Friend hung up on us");
 | 
			
		||||
                invoke_callback(call, MSI_ON_END);
 | 
			
		||||
                LOGGER_INFO(log, "Friend hung up on us");
 | 
			
		||||
                invoke_callback(log, call, MSI_ON_END);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case MSI_CALL_REQUESTING: {
 | 
			
		||||
                /* Reject */
 | 
			
		||||
                LOGGER_INFO(call->session->messenger->log, "Friend rejected our call");
 | 
			
		||||
                invoke_callback(call, MSI_ON_END);
 | 
			
		||||
                LOGGER_INFO(log, "Friend rejected our call");
 | 
			
		||||
                invoke_callback(log, call, MSI_ON_END);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case MSI_CALL_REQUESTED: {
 | 
			
		||||
                /* Cancel */
 | 
			
		||||
                LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite");
 | 
			
		||||
                invoke_callback(call, MSI_ON_END);
 | 
			
		||||
                LOGGER_INFO(log, "Friend canceled call invite");
 | 
			
		||||
                invoke_callback(log, call, MSI_ON_END);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    kill_call(call);
 | 
			
		||||
    kill_call(log, call);
 | 
			
		||||
}
 | 
			
		||||
static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *user_data)
 | 
			
		||||
 | 
			
		||||
static void handle_msi_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length,
 | 
			
		||||
                              void *user_data)
 | 
			
		||||
{
 | 
			
		||||
    MSISession *session = (MSISession *)user_data;
 | 
			
		||||
    const ToxAV *toxav = (ToxAV *)tox_get_av_object(tox);
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(m->log, "Got msi message");
 | 
			
		||||
 | 
			
		||||
    MSIMessage msg;
 | 
			
		||||
 | 
			
		||||
    if (msg_parse_in(m->log, &msg, data, length) == -1) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "Error parsing message");
 | 
			
		||||
        send_error(m, friend_number, MSI_E_INVALID_MESSAGE);
 | 
			
		||||
    if (toxav == nullptr) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(m->log, "Successfully parsed message");
 | 
			
		||||
    const Logger *log = toxav_get_logger(toxav);
 | 
			
		||||
 | 
			
		||||
    if (length < 2) {
 | 
			
		||||
        LOGGER_ERROR(log, "MSI packet is less than 2 bytes in size");
 | 
			
		||||
        // we need more than the ID byte for MSI messages
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const uint16_t payload_length = (uint16_t)(length - 1);
 | 
			
		||||
 | 
			
		||||
    // Zoff: do not show the first byte, its always "PACKET_ID_MSI"
 | 
			
		||||
    const uint8_t *data_strip_id_byte = data + 1;
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(log, "Got msi message");
 | 
			
		||||
 | 
			
		||||
    MSISession *session = tox_av_msi_get(toxav);
 | 
			
		||||
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MSIMessage msg;
 | 
			
		||||
 | 
			
		||||
    if (msg_parse_in(log, &msg, data_strip_id_byte, payload_length) == -1) {
 | 
			
		||||
        LOGGER_WARNING(log, "Error parsing message");
 | 
			
		||||
        send_error(log, tox, friend_number, MSI_E_INVALID_MESSAGE);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(log, "Successfully parsed message");
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(session->mutex);
 | 
			
		||||
    MSICall *call = get_call(session, friend_number);
 | 
			
		||||
 | 
			
		||||
    if (call == nullptr) {
 | 
			
		||||
        if (msg.request.value != REQU_INIT) {
 | 
			
		||||
            send_error(m, friend_number, MSI_E_STRAY_MESSAGE);
 | 
			
		||||
            send_error(log, tox, friend_number, MSI_E_STRAY_MESSAGE);
 | 
			
		||||
            pthread_mutex_unlock(session->mutex);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -872,7 +966,7 @@ static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_
 | 
			
		||||
        call = new_call(session, friend_number);
 | 
			
		||||
 | 
			
		||||
        if (call == nullptr) {
 | 
			
		||||
            send_error(m, friend_number, MSI_E_SYSTEM);
 | 
			
		||||
            send_error(log, tox, friend_number, MSI_E_SYSTEM);
 | 
			
		||||
            pthread_mutex_unlock(session->mutex);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -880,17 +974,17 @@ static void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_
 | 
			
		||||
 | 
			
		||||
    switch (msg.request.value) {
 | 
			
		||||
        case REQU_INIT: {
 | 
			
		||||
            handle_init(call, &msg);
 | 
			
		||||
            handle_init(log, call, &msg);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case REQU_PUSH: {
 | 
			
		||||
            handle_push(call, &msg);
 | 
			
		||||
            handle_push(log, call, &msg);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case REQU_POP: {
 | 
			
		||||
            handle_pop(call, &msg); /* always kills the call */
 | 
			
		||||
            handle_pop(log, call, &msg); /* always kills the call */
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								external/toxcore/c-toxcore/toxav/msi.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										37
									
								
								external/toxcore/c-toxcore/toxav/msi.h
									
									
									
									
										vendored
									
									
								
							@@ -11,7 +11,6 @@
 | 
			
		||||
#include "audio.h"
 | 
			
		||||
#include "video.h"
 | 
			
		||||
 | 
			
		||||
#include "../toxcore/Messenger.h"
 | 
			
		||||
#include "../toxcore/logger.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -42,22 +41,22 @@ typedef enum MSICapabilities {
 | 
			
		||||
 * Call state identifiers.
 | 
			
		||||
 */
 | 
			
		||||
typedef enum MSICallState {
 | 
			
		||||
    MSI_CALL_INACTIVE, /* Default */
 | 
			
		||||
    MSI_CALL_ACTIVE,
 | 
			
		||||
    MSI_CALL_REQUESTING, /* when sending call invite */
 | 
			
		||||
    MSI_CALL_REQUESTED, /* when getting call invite */
 | 
			
		||||
    MSI_CALL_INACTIVE = 0, /* Default */
 | 
			
		||||
    MSI_CALL_ACTIVE = 1,
 | 
			
		||||
    MSI_CALL_REQUESTING = 2, /* when sending call invite */
 | 
			
		||||
    MSI_CALL_REQUESTED = 3, /* when getting call invite */
 | 
			
		||||
} MSICallState;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Callbacks ids that handle the states
 | 
			
		||||
 */
 | 
			
		||||
typedef enum MSICallbackID {
 | 
			
		||||
    MSI_ON_INVITE, /* Incoming call */
 | 
			
		||||
    MSI_ON_START, /* Call (RTP transmission) started */
 | 
			
		||||
    MSI_ON_END, /* Call that was active ended */
 | 
			
		||||
    MSI_ON_ERROR, /* On protocol error */
 | 
			
		||||
    MSI_ON_PEERTIMEOUT, /* Peer timed out; stop the call */
 | 
			
		||||
    MSI_ON_CAPABILITIES, /* Peer requested capabilities change */
 | 
			
		||||
    MSI_ON_INVITE = 0, /* Incoming call */
 | 
			
		||||
    MSI_ON_START = 1, /* Call (RTP transmission) started */
 | 
			
		||||
    MSI_ON_END = 2, /* Call that was active ended */
 | 
			
		||||
    MSI_ON_ERROR = 3, /* On protocol error */
 | 
			
		||||
    MSI_ON_PEERTIMEOUT = 4, /* Peer timed out; stop the call */
 | 
			
		||||
    MSI_ON_CAPABILITIES = 5, /* Peer requested capabilities change */
 | 
			
		||||
} MSICallbackID;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -96,7 +95,7 @@ typedef struct MSISession {
 | 
			
		||||
    uint32_t        calls_head;
 | 
			
		||||
 | 
			
		||||
    void           *av;
 | 
			
		||||
    Messenger      *messenger;
 | 
			
		||||
    Tox            *tox;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_t mutex[1];
 | 
			
		||||
 | 
			
		||||
@@ -111,11 +110,11 @@ typedef struct MSISession {
 | 
			
		||||
/**
 | 
			
		||||
 * Start the control session.
 | 
			
		||||
 */
 | 
			
		||||
MSISession *msi_new(Messenger *m);
 | 
			
		||||
MSISession *msi_new(const Logger *log, Tox *tox);
 | 
			
		||||
/**
 | 
			
		||||
 * Terminate control session. NOTE: all calls will be freed
 | 
			
		||||
 */
 | 
			
		||||
int msi_kill(MSISession *session, const Logger *log);
 | 
			
		||||
int msi_kill(const Logger *log, Tox *tox, MSISession *session);
 | 
			
		||||
/**
 | 
			
		||||
 * Callback setters.
 | 
			
		||||
 */
 | 
			
		||||
@@ -128,18 +127,20 @@ void msi_callback_capabilities(MSISession *session, msi_action_cb *callback);
 | 
			
		||||
/**
 | 
			
		||||
 * Send invite request to friend_number.
 | 
			
		||||
 */
 | 
			
		||||
int msi_invite(MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities);
 | 
			
		||||
int msi_invite(const Logger *log, MSISession *session, MSICall **call, uint32_t friend_number, uint8_t capabilities);
 | 
			
		||||
/**
 | 
			
		||||
 * Hangup call. NOTE: `call` will be freed
 | 
			
		||||
 */
 | 
			
		||||
int msi_hangup(MSICall *call);
 | 
			
		||||
int msi_hangup(const Logger *log, MSICall *call);
 | 
			
		||||
/**
 | 
			
		||||
 * Answer call request.
 | 
			
		||||
 */
 | 
			
		||||
int msi_answer(MSICall *call, uint8_t capabilities);
 | 
			
		||||
int msi_answer(const Logger *log, MSICall *call, uint8_t capabilities);
 | 
			
		||||
/**
 | 
			
		||||
 * Change capabilities of the call.
 | 
			
		||||
 */
 | 
			
		||||
int msi_change_capabilities(MSICall *call, uint8_t capabilities);
 | 
			
		||||
int msi_change_capabilities(const Logger *log, MSICall *call, uint8_t capabilities);
 | 
			
		||||
 | 
			
		||||
bool check_peer_offline_status(const Logger *log, const Tox *tox, MSISession *session, uint32_t friend_number);
 | 
			
		||||
 | 
			
		||||
#endif /* C_TOXCORE_TOXAV_MSI_H */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										395
									
								
								external/toxcore/c-toxcore/toxav/rtp.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										395
									
								
								external/toxcore/c-toxcore/toxav/rtp.c
									
									
									
									
										vendored
									
									
								
							@@ -9,12 +9,16 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "bwcontroller.h"
 | 
			
		||||
#include <sodium.h>
 | 
			
		||||
 | 
			
		||||
#include "bwcontroller.h"
 | 
			
		||||
#include "toxav_hacks.h"
 | 
			
		||||
 | 
			
		||||
#include "../toxcore/Messenger.h"
 | 
			
		||||
#include "../toxcore/ccompat.h"
 | 
			
		||||
#include "../toxcore/logger.h"
 | 
			
		||||
#include "../toxcore/mono_time.h"
 | 
			
		||||
#include "../toxcore/net_crypto.h"
 | 
			
		||||
#include "../toxcore/tox_private.h"
 | 
			
		||||
#include "../toxcore/util.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -23,30 +27,15 @@
 | 
			
		||||
 */
 | 
			
		||||
#define VIDEO_KEEP_KEYFRAME_IN_BUFFER_FOR_MS 15
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * return -1 on failure, 0 on success
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static int rtp_send_custom_lossy_packet(Tox *tox, int32_t friendnumber, const uint8_t *data, uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
    Tox_Err_Friend_Custom_Packet error;
 | 
			
		||||
    tox_friend_send_lossy_packet(tox, friendnumber, data, (size_t)length, &error);
 | 
			
		||||
 | 
			
		||||
    if (error == TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// allocate_len is NOT including header!
 | 
			
		||||
static struct RTPMessage *new_message(const struct RTPHeader *header, size_t allocate_len, const uint8_t *data,
 | 
			
		||||
                                      uint16_t data_length)
 | 
			
		||||
static struct RTPMessage *new_message(const Logger *log, const struct RTPHeader *header, size_t allocate_len,
 | 
			
		||||
                                      const uint8_t *data, uint16_t data_length)
 | 
			
		||||
{
 | 
			
		||||
    assert(allocate_len >= data_length);
 | 
			
		||||
    struct RTPMessage *msg = (struct RTPMessage *)calloc(1, sizeof(struct RTPMessage) + allocate_len);
 | 
			
		||||
 | 
			
		||||
    if (msg == nullptr) {
 | 
			
		||||
        LOGGER_DEBUG(log, "Could not allocate RTPMessage buffer");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -241,7 +230,7 @@ static struct RTPMessage *process_frame(const Logger *log, struct RTPWorkBufferL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param log A logger.
 | 
			
		||||
 * @param log A pointer to the Logger object.
 | 
			
		||||
 * @param wkbl The list of in-progress frames, i.e. all the slots.
 | 
			
		||||
 * @param slot_id The slot we want to fill the data into.
 | 
			
		||||
 * @param is_keyframe Whether the data is part of a key frame.
 | 
			
		||||
@@ -309,7 +298,7 @@ static bool fill_data_into_slot(const Logger *log, struct RTPWorkBufferList *wkb
 | 
			
		||||
    return slot->received_len == header->data_length_full;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void update_bwc_values(const Logger *log, RTPSession *session, const struct RTPMessage *msg)
 | 
			
		||||
static void update_bwc_values(RTPSession *session, const struct RTPMessage *msg)
 | 
			
		||||
{
 | 
			
		||||
    if (session->first_packets_counter < DISMISS_FIRST_LOST_VIDEO_PACKET_COUNT) {
 | 
			
		||||
        ++session->first_packets_counter;
 | 
			
		||||
@@ -319,7 +308,7 @@ static void update_bwc_values(const Logger *log, RTPSession *session, const stru
 | 
			
		||||
        bwc_add_recv(session->bwc, data_length_full);
 | 
			
		||||
 | 
			
		||||
        if (received_length_full < data_length_full) {
 | 
			
		||||
            LOGGER_DEBUG(log, "BWC: full length=%u received length=%d", data_length_full, received_length_full);
 | 
			
		||||
            LOGGER_DEBUG(session->log, "BWC: full length=%u received length=%d", data_length_full, received_length_full);
 | 
			
		||||
            bwc_add_lost(session->bwc, data_length_full - received_length_full);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -347,22 +336,16 @@ static void update_bwc_values(const Logger *log, RTPSession *session, const stru
 | 
			
		||||
 * @retval -1 on error.
 | 
			
		||||
 * @retval 0 on success.
 | 
			
		||||
 */
 | 
			
		||||
static int handle_video_packet(RTPSession *session, const struct RTPHeader *header,
 | 
			
		||||
                               const uint8_t *incoming_data, uint16_t incoming_data_length, const Logger *log)
 | 
			
		||||
static int handle_video_packet(const Logger *log, RTPSession *session, const struct RTPHeader *header,
 | 
			
		||||
                               const uint8_t *incoming_data, uint16_t incoming_data_length)
 | 
			
		||||
{
 | 
			
		||||
    // Full frame length in bytes. The frame may be split into multiple packets,
 | 
			
		||||
    // but this value is the complete assembled frame size.
 | 
			
		||||
    const uint32_t full_frame_length = header->data_length_full;
 | 
			
		||||
 | 
			
		||||
    // Current offset in the frame. If this is the first packet of a multipart
 | 
			
		||||
    // frame or it's not a multipart frame, then this value is 0.
 | 
			
		||||
    const uint32_t offset = header->offset_full; // without header
 | 
			
		||||
 | 
			
		||||
    // The sender tells us whether this is a key frame.
 | 
			
		||||
    const bool is_keyframe = (header->flags & RTP_KEY_FRAME) != 0;
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(log, "-- handle_video_packet -- full lens=%u len=%u offset=%u is_keyframe=%s",
 | 
			
		||||
                 (unsigned)incoming_data_length, (unsigned)full_frame_length, (unsigned)offset, is_keyframe ? "K" : ".");
 | 
			
		||||
    LOGGER_DEBUG(log, "wkbl->next_free_entry:003=%d", session->work_buffer_list->next_free_entry);
 | 
			
		||||
 | 
			
		||||
    const bool is_multipart = full_frame_length != incoming_data_length;
 | 
			
		||||
@@ -387,10 +370,13 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head
 | 
			
		||||
        // get_slot just told us it's full, so process_frame must return non-null.
 | 
			
		||||
        assert(m_new != nullptr);
 | 
			
		||||
 | 
			
		||||
        LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-001a b0=%d b1=%d", (int)m_new->data[0], (int)m_new->data[1]);
 | 
			
		||||
        update_bwc_values(log, session, m_new);
 | 
			
		||||
        LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-001a b0=%d b1=%d", (int)m_new->data[0],
 | 
			
		||||
                     (int)m_new->data[1]);
 | 
			
		||||
        update_bwc_values(session, m_new);
 | 
			
		||||
        // Pass ownership of m_new to the callback.
 | 
			
		||||
        session->mcb(session->m->mono_time, session->cs, m_new);
 | 
			
		||||
        Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
 | 
			
		||||
        assert(mt != nullptr);
 | 
			
		||||
        session->mcb(mt, session->cs, m_new);
 | 
			
		||||
        // Now we no longer own m_new.
 | 
			
		||||
        m_new = nullptr;
 | 
			
		||||
 | 
			
		||||
@@ -425,9 +411,12 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head
 | 
			
		||||
    struct RTPMessage *m_new = process_frame(log, session->work_buffer_list, slot_id);
 | 
			
		||||
 | 
			
		||||
    if (m_new != nullptr) {
 | 
			
		||||
        LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-003a b0=%d b1=%d", (int)m_new->data[0], (int)m_new->data[1]);
 | 
			
		||||
        update_bwc_values(log, session, m_new);
 | 
			
		||||
        session->mcb(session->m->mono_time, session->cs, m_new);
 | 
			
		||||
        LOGGER_DEBUG(log, "-- handle_video_packet -- CALLBACK-003a b0=%d b1=%d", (int)m_new->data[0],
 | 
			
		||||
                     (int)m_new->data[1]);
 | 
			
		||||
        update_bwc_values(session, m_new);
 | 
			
		||||
        Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
 | 
			
		||||
        assert(mt != nullptr);
 | 
			
		||||
        session->mcb(mt, session->cs, m_new);
 | 
			
		||||
 | 
			
		||||
        m_new = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
@@ -436,80 +425,113 @@ static int handle_video_packet(RTPSession *session, const struct RTPHeader *head
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @retval -1 on error.
 | 
			
		||||
 * @retval 0 on success.
 | 
			
		||||
 * receive custom lossypackets and process them. they can be incoming audio or video packets
 | 
			
		||||
 */
 | 
			
		||||
static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object)
 | 
			
		||||
void handle_rtp_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
    RTPSession *session = (RTPSession *)object;
 | 
			
		||||
    ToxAV *toxav = (ToxAV *)tox_get_av_object(tox);
 | 
			
		||||
 | 
			
		||||
    if (session == nullptr || length < RTP_HEADER_SIZE + 1) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "No session or invalid length of received buffer!");
 | 
			
		||||
        return -1;
 | 
			
		||||
    if (toxav == nullptr) {
 | 
			
		||||
        // LOGGER_WARNING(log, "ToxAV is NULL!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const Logger *log = toxav_get_logger(toxav);
 | 
			
		||||
 | 
			
		||||
    if (length < RTP_HEADER_SIZE + 1) {
 | 
			
		||||
        LOGGER_WARNING(log, "Invalid length of received buffer!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ToxAVCall *call = call_get(toxav, friend_number);
 | 
			
		||||
 | 
			
		||||
    if (call == nullptr) {
 | 
			
		||||
        LOGGER_WARNING(log, "ToxAVCall is NULL!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RTPSession *session = rtp_session_get(call, data[0]);
 | 
			
		||||
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        LOGGER_WARNING(log, "No session!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!session->rtp_receive_active) {
 | 
			
		||||
        LOGGER_WARNING(log, "receiving not allowed!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Get the packet type.
 | 
			
		||||
    const uint8_t packet_type = data[0];
 | 
			
		||||
    ++data;
 | 
			
		||||
    --length;
 | 
			
		||||
    const uint8_t *payload = &data[1];
 | 
			
		||||
    // TODO(Zoff): is this ok?
 | 
			
		||||
    const uint16_t payload_size = (uint16_t)length - 1;
 | 
			
		||||
 | 
			
		||||
    // Unpack the header.
 | 
			
		||||
    struct RTPHeader header;
 | 
			
		||||
    rtp_header_unpack(data, &header);
 | 
			
		||||
    rtp_header_unpack(payload, &header);
 | 
			
		||||
 | 
			
		||||
    if (header.pt != packet_type % 128) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "RTPHeader packet type and Tox protocol packet type did not agree: %d != %d",
 | 
			
		||||
        LOGGER_WARNING(log, "RTPHeader packet type and Tox protocol packet type did not agree: %d != %d",
 | 
			
		||||
                       header.pt, packet_type % 128);
 | 
			
		||||
        return -1;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (header.pt != session->payload_type % 128) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "RTPHeader packet type does not match this session's payload type: %d != %d",
 | 
			
		||||
        LOGGER_WARNING(log, "RTPHeader packet type does not match this session's payload type: %d != %d",
 | 
			
		||||
                       header.pt, session->payload_type % 128);
 | 
			
		||||
        return -1;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((header.flags & RTP_LARGE_FRAME) != 0 && header.offset_full >= header.data_length_full) {
 | 
			
		||||
        LOGGER_ERROR(m->log, "Invalid video packet: frame offset (%u) >= full frame length (%u)",
 | 
			
		||||
        LOGGER_ERROR(log, "Invalid video packet: frame offset (%u) >= full frame length (%u)",
 | 
			
		||||
                     (unsigned)header.offset_full, (unsigned)header.data_length_full);
 | 
			
		||||
        return -1;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (header.offset_lower >= header.data_length_lower) {
 | 
			
		||||
        LOGGER_ERROR(m->log, "Invalid old protocol video packet: frame offset (%u) >= full frame length (%u)",
 | 
			
		||||
        LOGGER_ERROR(log, "Invalid old protocol video packet: frame offset (%u) >= full frame length (%u)",
 | 
			
		||||
                     (unsigned)header.offset_lower, (unsigned)header.data_length_lower);
 | 
			
		||||
        return -1;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(m->log, "header.pt %d, video %d", (uint8_t)header.pt, RTP_TYPE_VIDEO % 128);
 | 
			
		||||
    LOGGER_DEBUG(log, "header.pt %d, video %d", (uint8_t)header.pt, RTP_TYPE_VIDEO % 128);
 | 
			
		||||
 | 
			
		||||
    // The sender uses the new large-frame capable protocol and is sending a
 | 
			
		||||
    // video packet.
 | 
			
		||||
    if ((header.flags & RTP_LARGE_FRAME) != 0 && header.pt == (RTP_TYPE_VIDEO % 128)) {
 | 
			
		||||
        return handle_video_packet(session, &header, data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE, m->log);
 | 
			
		||||
        handle_video_packet(log, session, &header, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // everything below here is for the old 16 bit protocol ------------------
 | 
			
		||||
 | 
			
		||||
    if (header.data_length_lower == length - RTP_HEADER_SIZE) {
 | 
			
		||||
    if (header.data_length_lower == payload_size - RTP_HEADER_SIZE) {
 | 
			
		||||
        /* The message is sent in single part */
 | 
			
		||||
 | 
			
		||||
        /* Message is not late; pick up the latest parameters */
 | 
			
		||||
        session->rsequnum = header.sequnum;
 | 
			
		||||
        session->rtimestamp = header.timestamp;
 | 
			
		||||
        bwc_add_recv(session->bwc, length);
 | 
			
		||||
        bwc_add_recv(session->bwc, payload_size);
 | 
			
		||||
 | 
			
		||||
        /* Invoke processing of active multiparted message */
 | 
			
		||||
        if (session->mp != nullptr) {
 | 
			
		||||
            session->mcb(session->m->mono_time, session->cs, session->mp);
 | 
			
		||||
            Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
 | 
			
		||||
            assert(mt != nullptr);
 | 
			
		||||
            session->mcb(mt, session->cs, session->mp);
 | 
			
		||||
            session->mp = nullptr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* The message came in the allowed time;
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        return session->mcb(session->m->mono_time, session->cs, new_message(&header, length - RTP_HEADER_SIZE,
 | 
			
		||||
                            data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE));
 | 
			
		||||
        session->mp = new_message(log, &header, payload_size - RTP_HEADER_SIZE, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE);
 | 
			
		||||
        Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
 | 
			
		||||
        assert(mt != nullptr);
 | 
			
		||||
        session->mcb(mt, session->cs, session->mp);
 | 
			
		||||
        session->mp = nullptr;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* The message is sent in multiple parts */
 | 
			
		||||
@@ -527,24 +549,26 @@ static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t
 | 
			
		||||
            /* First case */
 | 
			
		||||
 | 
			
		||||
            /* Make sure we have enough allocated memory */
 | 
			
		||||
            if (session->mp->header.data_length_lower - session->mp->len < length - RTP_HEADER_SIZE ||
 | 
			
		||||
            if (session->mp->header.data_length_lower - session->mp->len < payload_size - RTP_HEADER_SIZE ||
 | 
			
		||||
                    session->mp->header.data_length_lower <= header.offset_lower) {
 | 
			
		||||
                /* There happened to be some corruption on the stream;
 | 
			
		||||
                 * continue wihtout this part
 | 
			
		||||
                 */
 | 
			
		||||
                return 0;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            memcpy(session->mp->data + header.offset_lower, data + RTP_HEADER_SIZE,
 | 
			
		||||
                   length - RTP_HEADER_SIZE);
 | 
			
		||||
            session->mp->len += length - RTP_HEADER_SIZE;
 | 
			
		||||
            bwc_add_recv(session->bwc, length);
 | 
			
		||||
            memcpy(session->mp->data + header.offset_lower, &payload[RTP_HEADER_SIZE],
 | 
			
		||||
                   payload_size - RTP_HEADER_SIZE);
 | 
			
		||||
            session->mp->len += payload_size - RTP_HEADER_SIZE;
 | 
			
		||||
            bwc_add_recv(session->bwc, payload_size);
 | 
			
		||||
 | 
			
		||||
            if (session->mp->len == session->mp->header.data_length_lower) {
 | 
			
		||||
                /* Received a full message; now push it for the further
 | 
			
		||||
                 * processing.
 | 
			
		||||
                 */
 | 
			
		||||
                session->mcb(session->m->mono_time, session->cs, session->mp);
 | 
			
		||||
                Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
 | 
			
		||||
                assert(mt != nullptr);
 | 
			
		||||
                session->mcb(mt, session->cs, session->mp);
 | 
			
		||||
                session->mp = nullptr;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -553,17 +577,19 @@ static int handle_rtp_packet(Messenger *m, uint32_t friend_number, const uint8_t
 | 
			
		||||
                /* The received message part is from the old message;
 | 
			
		||||
                 * discard it.
 | 
			
		||||
                 */
 | 
			
		||||
                return 0;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Push the previous message for processing */
 | 
			
		||||
            session->mcb(session->m->mono_time, session->cs, session->mp);
 | 
			
		||||
            Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
 | 
			
		||||
            assert(mt != nullptr);
 | 
			
		||||
            session->mcb(mt, session->cs, session->mp);
 | 
			
		||||
 | 
			
		||||
            session->mp = nullptr;
 | 
			
		||||
            goto NEW_MULTIPARTED;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        /* In this case threat the message as if it was received in order
 | 
			
		||||
        /* In this case treat the message as if it was received in order
 | 
			
		||||
         */
 | 
			
		||||
        /* This is also a point for new multiparted messages */
 | 
			
		||||
NEW_MULTIPARTED:
 | 
			
		||||
@@ -571,21 +597,21 @@ NEW_MULTIPARTED:
 | 
			
		||||
        /* Message is not late; pick up the latest parameters */
 | 
			
		||||
        session->rsequnum = header.sequnum;
 | 
			
		||||
        session->rtimestamp = header.timestamp;
 | 
			
		||||
        bwc_add_recv(session->bwc, length);
 | 
			
		||||
        bwc_add_recv(session->bwc, payload_size);
 | 
			
		||||
 | 
			
		||||
        /* Store message.
 | 
			
		||||
         */
 | 
			
		||||
        session->mp = new_message(&header, header.data_length_lower, data + RTP_HEADER_SIZE, length - RTP_HEADER_SIZE);
 | 
			
		||||
        session->mp = new_message(log, &header, header.data_length_lower, &payload[RTP_HEADER_SIZE], payload_size - RTP_HEADER_SIZE);
 | 
			
		||||
 | 
			
		||||
        if (session->mp != nullptr) {
 | 
			
		||||
            memmove(session->mp->data + header.offset_lower, session->mp->data, session->mp->len);
 | 
			
		||||
        } else {
 | 
			
		||||
            LOGGER_WARNING(m->log, "new_message() returned a null pointer");
 | 
			
		||||
            return -1;
 | 
			
		||||
            LOGGER_WARNING(log, "new_message() returned a null pointer");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
size_t rtp_header_pack(uint8_t *const rdata, const struct RTPHeader *header)
 | 
			
		||||
@@ -647,24 +673,29 @@ size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header)
 | 
			
		||||
    return p - data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnumber,
 | 
			
		||||
static uint32_t rtp_random_u32(void)
 | 
			
		||||
{
 | 
			
		||||
    // HINT: uses libsodium function
 | 
			
		||||
    return randombytes_random();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber,
 | 
			
		||||
                    BWController *bwc, void *cs, rtp_m_cb *mcb)
 | 
			
		||||
{
 | 
			
		||||
    assert(mcb != nullptr);
 | 
			
		||||
    assert(cs != nullptr);
 | 
			
		||||
    assert(m != nullptr);
 | 
			
		||||
 | 
			
		||||
    RTPSession *session = (RTPSession *)calloc(1, sizeof(RTPSession));
 | 
			
		||||
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "Alloc failed! Program might misbehave!");
 | 
			
		||||
        LOGGER_WARNING(log, "Alloc failed! Program might misbehave!");
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    session->work_buffer_list = (struct RTPWorkBufferList *)calloc(1, sizeof(struct RTPWorkBufferList));
 | 
			
		||||
 | 
			
		||||
    if (session->work_buffer_list == nullptr) {
 | 
			
		||||
        LOGGER_ERROR(m->log, "out of memory while allocating work buffer list");
 | 
			
		||||
        LOGGER_ERROR(log, "out of memory while allocating work buffer list");
 | 
			
		||||
        free(session);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
@@ -672,11 +703,12 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum
 | 
			
		||||
    // First entry is free.
 | 
			
		||||
    session->work_buffer_list->next_free_entry = 0;
 | 
			
		||||
 | 
			
		||||
    session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : random_u32(m->rng);
 | 
			
		||||
    session->ssrc = payload_type == RTP_TYPE_VIDEO ? 0 : rtp_random_u32(); // Zoff: what is this??
 | 
			
		||||
    session->payload_type = payload_type;
 | 
			
		||||
    session->m = m;
 | 
			
		||||
    session->tox = tox;
 | 
			
		||||
    session->toxav = toxav;
 | 
			
		||||
    session->friend_number = friendnumber;
 | 
			
		||||
    session->rtp_receive_active = true;
 | 
			
		||||
 | 
			
		||||
    // set NULL just in case
 | 
			
		||||
    session->mp = nullptr;
 | 
			
		||||
@@ -687,26 +719,18 @@ RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnum
 | 
			
		||||
    session->cs = cs;
 | 
			
		||||
    session->mcb = mcb;
 | 
			
		||||
 | 
			
		||||
    if (-1 == rtp_allow_receiving(session)) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "Failed to start rtp receiving mode");
 | 
			
		||||
        free(session->work_buffer_list);
 | 
			
		||||
        free(session);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return session;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rtp_kill(RTPSession *session)
 | 
			
		||||
void rtp_kill(const Logger *log, RTPSession *session)
 | 
			
		||||
{
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        LOGGER_WARNING(log, "No session");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->m->log, "Terminated RTP session: %p", (void *)session);
 | 
			
		||||
    rtp_stop_receiving(session);
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->m->log, "Terminated RTP session V3 work_buffer_list->next_free_entry: %d",
 | 
			
		||||
    LOGGER_DEBUG(log, "Terminated RTP session: %p", (void *)session);
 | 
			
		||||
    LOGGER_DEBUG(log, "Terminated RTP session V3 work_buffer_list->next_free_entry: %d",
 | 
			
		||||
                 (int)session->work_buffer_list->next_free_entry);
 | 
			
		||||
 | 
			
		||||
    for (int8_t i = 0; i < session->work_buffer_list->next_free_entry; ++i) {
 | 
			
		||||
@@ -716,36 +740,95 @@ void rtp_kill(RTPSession *session)
 | 
			
		||||
    free(session);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rtp_allow_receiving(RTPSession *session)
 | 
			
		||||
void rtp_allow_receiving_mark(RTPSession *session)
 | 
			
		||||
{
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    if (session != nullptr) {
 | 
			
		||||
        session->rtp_receive_active = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_callback_rtp_packet(session->m, session->friend_number, session->payload_type,
 | 
			
		||||
                              handle_rtp_packet, session) == -1) {
 | 
			
		||||
        LOGGER_WARNING(session->m->log, "Failed to register rtp receive handler");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->m->log, "Started receiving on session: %p", (void *)session);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rtp_stop_receiving(RTPSession *session)
 | 
			
		||||
void rtp_stop_receiving_mark(RTPSession *session)
 | 
			
		||||
{
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    if (session != nullptr) {
 | 
			
		||||
        session->rtp_receive_active = false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rtp_allow_receiving(Tox *tox)
 | 
			
		||||
{
 | 
			
		||||
    // register callback
 | 
			
		||||
    tox_callback_friend_lossy_packet_per_pktid(tox, handle_rtp_packet, RTP_TYPE_AUDIO);
 | 
			
		||||
    tox_callback_friend_lossy_packet_per_pktid(tox, handle_rtp_packet, RTP_TYPE_VIDEO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rtp_stop_receiving(Tox *tox)
 | 
			
		||||
{
 | 
			
		||||
    // UN-register callback
 | 
			
		||||
    tox_callback_friend_lossy_packet_per_pktid(tox, nullptr, RTP_TYPE_AUDIO);
 | 
			
		||||
    tox_callback_friend_lossy_packet_per_pktid(tox, nullptr, RTP_TYPE_VIDEO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rtp_send_piece(const Logger *log, Tox *tox, uint32_t friend_number, const struct RTPHeader *header,
 | 
			
		||||
                           const uint8_t *data, uint8_t *rdata, uint16_t length)
 | 
			
		||||
{
 | 
			
		||||
    rtp_header_pack(rdata + 1, header);
 | 
			
		||||
    memcpy(rdata + 1 + RTP_HEADER_SIZE, data, length);
 | 
			
		||||
 | 
			
		||||
    Tox_Err_Friend_Custom_Packet error;
 | 
			
		||||
    tox_friend_send_lossy_packet(tox, friend_number,
 | 
			
		||||
                                 rdata, length + RTP_HEADER_SIZE + 1, &error);
 | 
			
		||||
 | 
			
		||||
    if (error != TOX_ERR_FRIEND_CUSTOM_PACKET_OK) {
 | 
			
		||||
        char *netstrerror = net_new_strerror(net_error());
 | 
			
		||||
        LOGGER_WARNING(log, "RTP send failed (len: %d)! tox error: %d, net error: %s",
 | 
			
		||||
                       length + RTP_HEADER_SIZE + 1, error, netstrerror);
 | 
			
		||||
        net_kill_strerror(netstrerror);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct RTPHeader rtp_default_header(const RTPSession *session, uint32_t length, bool is_keyframe)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t length_safe = (uint16_t)length;
 | 
			
		||||
 | 
			
		||||
    if (length > UINT16_MAX) {
 | 
			
		||||
        length_safe = UINT16_MAX;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_callback_rtp_packet(session->m, session->friend_number, session->payload_type, nullptr, nullptr);
 | 
			
		||||
    struct RTPHeader header = {0};
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(session->m->log, "Stopped receiving on session: %p", (void *)session);
 | 
			
		||||
    return 0;
 | 
			
		||||
    if (is_keyframe) {
 | 
			
		||||
        header.flags |= RTP_KEY_FRAME;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (session->payload_type == RTP_TYPE_VIDEO) {
 | 
			
		||||
        header.flags |= RTP_LARGE_FRAME;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    header.ve = 2;  // this is unused in toxav
 | 
			
		||||
    header.pe = 0;
 | 
			
		||||
    header.xe = 0;
 | 
			
		||||
    header.cc = 0;
 | 
			
		||||
    header.ma = 0;
 | 
			
		||||
    header.pt = session->payload_type % 128;
 | 
			
		||||
    header.sequnum = session->sequnum;
 | 
			
		||||
    Mono_Time *mt = toxav_get_av_mono_time(session->toxav);
 | 
			
		||||
    if (mt != nullptr) {
 | 
			
		||||
        header.timestamp = current_time_monotonic(mt);
 | 
			
		||||
    } else {
 | 
			
		||||
        header.timestamp = 0;
 | 
			
		||||
    }
 | 
			
		||||
    header.ssrc = session->ssrc;
 | 
			
		||||
    header.offset_lower = 0;
 | 
			
		||||
    header.data_length_lower = length_safe;
 | 
			
		||||
    header.data_length_full = length; // without header
 | 
			
		||||
    header.offset_lower = 0;
 | 
			
		||||
    header.offset_full = 0;
 | 
			
		||||
 | 
			
		||||
    return header;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Send a frame of audio or video data, chunked in @ref RTPMessage instances.
 | 
			
		||||
 * @brief Send a frame of audio or video data, chunked in @ref RTPMessage instances.
 | 
			
		||||
 *
 | 
			
		||||
 * @param session The A/V session to send the data for.
 | 
			
		||||
 * @param data A byte array of length @p length.
 | 
			
		||||
@@ -753,77 +836,27 @@ int rtp_stop_receiving(RTPSession *session)
 | 
			
		||||
 * @param is_keyframe Whether this video frame is a key frame. If it is an
 | 
			
		||||
 *   audio frame, this parameter is ignored.
 | 
			
		||||
 */
 | 
			
		||||
int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
 | 
			
		||||
                  bool is_keyframe, const Logger *log)
 | 
			
		||||
int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, uint32_t length,
 | 
			
		||||
                  bool is_keyframe)
 | 
			
		||||
{
 | 
			
		||||
    if (session == nullptr) {
 | 
			
		||||
        LOGGER_ERROR(log, "No session!");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    struct RTPHeader header = {0};
 | 
			
		||||
 | 
			
		||||
    header.ve = 2;  // this is unused in toxav
 | 
			
		||||
 | 
			
		||||
    header.pe = 0;
 | 
			
		||||
 | 
			
		||||
    header.xe = 0;
 | 
			
		||||
 | 
			
		||||
    header.cc = 0;
 | 
			
		||||
 | 
			
		||||
    header.ma = 0;
 | 
			
		||||
 | 
			
		||||
    header.pt = session->payload_type % 128;
 | 
			
		||||
 | 
			
		||||
    header.sequnum = session->sequnum;
 | 
			
		||||
 | 
			
		||||
    header.timestamp = current_time_monotonic(session->m->mono_time);
 | 
			
		||||
 | 
			
		||||
    header.ssrc = session->ssrc;
 | 
			
		||||
 | 
			
		||||
    header.offset_lower = 0;
 | 
			
		||||
 | 
			
		||||
    // here the highest bits gets stripped anyway, no need to do keyframe bit magic here!
 | 
			
		||||
    header.data_length_lower = length;
 | 
			
		||||
 | 
			
		||||
    if (session->payload_type == RTP_TYPE_VIDEO) {
 | 
			
		||||
        header.flags = RTP_LARGE_FRAME;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint16_t length_safe = (uint16_t)length;
 | 
			
		||||
 | 
			
		||||
    if (length > UINT16_MAX) {
 | 
			
		||||
        length_safe = UINT16_MAX;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    header.data_length_lower = length_safe;
 | 
			
		||||
    header.data_length_full = length; // without header
 | 
			
		||||
    header.offset_lower = 0;
 | 
			
		||||
    header.offset_full = 0;
 | 
			
		||||
 | 
			
		||||
    if (is_keyframe) {
 | 
			
		||||
        header.flags |= RTP_KEY_FRAME;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const uint16_t rdata_size = min_u32(length + RTP_HEADER_SIZE + 1, MAX_CRYPTO_DATA_SIZE);
 | 
			
		||||
    VLA(uint8_t, rdata, rdata_size);
 | 
			
		||||
    memset(rdata, 0, rdata_size);
 | 
			
		||||
    rdata[0] = session->payload_type;  // packet id == payload_type
 | 
			
		||||
 | 
			
		||||
    struct RTPHeader header = rtp_default_header(session, length, is_keyframe);
 | 
			
		||||
 | 
			
		||||
    if (MAX_CRYPTO_DATA_SIZE > (length + RTP_HEADER_SIZE + 1)) {
 | 
			
		||||
        /*
 | 
			
		||||
         * The length is lesser than the maximum allowed length (including header)
 | 
			
		||||
         * Send the packet in single piece.
 | 
			
		||||
         */
 | 
			
		||||
        rtp_header_pack(rdata + 1, &header);
 | 
			
		||||
        memcpy(rdata + 1 + RTP_HEADER_SIZE, data, length);
 | 
			
		||||
 | 
			
		||||
        if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, rdata, rdata_size)) {
 | 
			
		||||
            char *netstrerror = net_new_strerror(net_error());
 | 
			
		||||
            LOGGER_WARNING(session->m->log, "RTP send failed (len: %u)! net error: %s",
 | 
			
		||||
                           rdata_size, netstrerror);
 | 
			
		||||
            net_kill_strerror(netstrerror);
 | 
			
		||||
        }
 | 
			
		||||
        assert(length < UINT16_MAX);
 | 
			
		||||
        rtp_send_piece(log, session->tox, session->friend_number, &header, data, rdata, length);
 | 
			
		||||
    } else {
 | 
			
		||||
        /*
 | 
			
		||||
         * The length is greater than the maximum allowed length (including header)
 | 
			
		||||
@@ -833,16 +866,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
 | 
			
		||||
        uint16_t piece = MAX_CRYPTO_DATA_SIZE - (RTP_HEADER_SIZE + 1);
 | 
			
		||||
 | 
			
		||||
        while ((length - sent) + RTP_HEADER_SIZE + 1 > MAX_CRYPTO_DATA_SIZE) {
 | 
			
		||||
            rtp_header_pack(rdata + 1, &header);
 | 
			
		||||
            memcpy(rdata + 1 + RTP_HEADER_SIZE, data + sent, piece);
 | 
			
		||||
 | 
			
		||||
            if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number,
 | 
			
		||||
                                                   rdata, piece + RTP_HEADER_SIZE + 1)) {
 | 
			
		||||
                char *netstrerror = net_new_strerror(net_error());
 | 
			
		||||
                LOGGER_WARNING(session->m->log, "RTP send failed (len: %d)! net error: %s",
 | 
			
		||||
                               piece + RTP_HEADER_SIZE + 1, netstrerror);
 | 
			
		||||
                net_kill_strerror(netstrerror);
 | 
			
		||||
            }
 | 
			
		||||
            rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece);
 | 
			
		||||
 | 
			
		||||
            sent += piece;
 | 
			
		||||
            header.offset_lower = sent;
 | 
			
		||||
@@ -853,16 +877,7 @@ int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
 | 
			
		||||
        piece = length - sent;
 | 
			
		||||
 | 
			
		||||
        if (piece != 0) {
 | 
			
		||||
            rtp_header_pack(rdata + 1, &header);
 | 
			
		||||
            memcpy(rdata + 1 + RTP_HEADER_SIZE, data + sent, piece);
 | 
			
		||||
 | 
			
		||||
            if (-1 == rtp_send_custom_lossy_packet(session->tox, session->friend_number, rdata,
 | 
			
		||||
                                                   piece + RTP_HEADER_SIZE + 1)) {
 | 
			
		||||
                char *netstrerror = net_new_strerror(net_error());
 | 
			
		||||
                LOGGER_WARNING(session->m->log, "RTP send failed (len: %d)! net error: %s",
 | 
			
		||||
                               piece + RTP_HEADER_SIZE + 1, netstrerror);
 | 
			
		||||
                net_kill_strerror(netstrerror);
 | 
			
		||||
            }
 | 
			
		||||
            rtp_send_piece(log, session->tox, session->friend_number, &header, data + sent, rdata, piece);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										30
									
								
								external/toxcore/c-toxcore/toxav/rtp.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								external/toxcore/c-toxcore/toxav/rtp.h
									
									
									
									
										vendored
									
									
								
							@@ -9,7 +9,6 @@
 | 
			
		||||
 | 
			
		||||
#include "bwcontroller.h"
 | 
			
		||||
 | 
			
		||||
#include "../toxcore/Messenger.h"
 | 
			
		||||
#include "../toxcore/logger.h"
 | 
			
		||||
#include "../toxcore/tox.h"
 | 
			
		||||
 | 
			
		||||
@@ -36,6 +35,11 @@ typedef enum RTP_Type {
 | 
			
		||||
    RTP_TYPE_VIDEO = 193,
 | 
			
		||||
} RTP_Type;
 | 
			
		||||
 | 
			
		||||
#ifndef TOXAV_DEFINED
 | 
			
		||||
#define TOXAV_DEFINED
 | 
			
		||||
typedef struct ToxAV ToxAV;
 | 
			
		||||
#endif /* TOXAV_DEFINED */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A bit mask (up to 64 bits) specifying features of the current frame affecting
 | 
			
		||||
 * the behaviour of the decoder.
 | 
			
		||||
@@ -157,14 +161,19 @@ typedef struct RTPSession {
 | 
			
		||||
    struct RTPMessage *mp; /* Expected parted message */
 | 
			
		||||
    struct RTPWorkBufferList *work_buffer_list;
 | 
			
		||||
    uint8_t  first_packets_counter; /* dismiss first few lost video packets */
 | 
			
		||||
    Messenger *m;
 | 
			
		||||
    const Logger *log;
 | 
			
		||||
    Tox *tox;
 | 
			
		||||
    ToxAV *toxav;
 | 
			
		||||
    uint32_t friend_number;
 | 
			
		||||
    bool rtp_receive_active; /* if this is set to false then incoming rtp packets will not be processed by handle_rtp_packet() */
 | 
			
		||||
    BWController *bwc;
 | 
			
		||||
    void *cs;
 | 
			
		||||
    rtp_m_cb *mcb;
 | 
			
		||||
} RTPSession;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void handle_rtp_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Serialise an RTPHeader to bytes to be sent over the network.
 | 
			
		||||
 *
 | 
			
		||||
@@ -183,13 +192,16 @@ size_t rtp_header_pack(uint8_t *rdata, const struct RTPHeader *header);
 | 
			
		||||
 */
 | 
			
		||||
size_t rtp_header_unpack(const uint8_t *data, struct RTPHeader *header);
 | 
			
		||||
 | 
			
		||||
RTPSession *rtp_new(int payload_type, Messenger *m, Tox *tox, uint32_t friendnumber,
 | 
			
		||||
RTPSession *rtp_new(const Logger *log, int payload_type, Tox *tox, ToxAV *toxav, uint32_t friendnumber,
 | 
			
		||||
                    BWController *bwc, void *cs, rtp_m_cb *mcb);
 | 
			
		||||
void rtp_kill(RTPSession *session);
 | 
			
		||||
int rtp_allow_receiving(RTPSession *session);
 | 
			
		||||
int rtp_stop_receiving(RTPSession *session);
 | 
			
		||||
void rtp_kill(const Logger *log, RTPSession *session);
 | 
			
		||||
void rtp_allow_receiving_mark(RTPSession *session);
 | 
			
		||||
void rtp_stop_receiving_mark(RTPSession *session);
 | 
			
		||||
void rtp_allow_receiving(Tox *tox);
 | 
			
		||||
void rtp_stop_receiving(Tox *tox);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Send a frame of audio or video data, chunked in @ref RTPMessage instances.
 | 
			
		||||
 * @brief Send a frame of audio or video data, chunked in @ref RTPMessage instances.
 | 
			
		||||
 *
 | 
			
		||||
 * @param session The A/V session to send the data for.
 | 
			
		||||
 * @param data A byte array of length @p length.
 | 
			
		||||
@@ -197,8 +209,8 @@ int rtp_stop_receiving(RTPSession *session);
 | 
			
		||||
 * @param is_keyframe Whether this video frame is a key frame. If it is an
 | 
			
		||||
 *   audio frame, this parameter is ignored.
 | 
			
		||||
 */
 | 
			
		||||
int rtp_send_data(RTPSession *session, const uint8_t *data, uint32_t length,
 | 
			
		||||
                  bool is_keyframe, const Logger *log);
 | 
			
		||||
int rtp_send_data(const Logger *log, RTPSession *session, const uint8_t *data, uint32_t length,
 | 
			
		||||
                  bool is_keyframe);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
} /* extern "C" */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										339
									
								
								external/toxcore/c-toxcore/toxav/toxav.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										339
									
								
								external/toxcore/c-toxcore/toxav/toxav.c
									
									
									
									
										vendored
									
									
								
							@@ -12,11 +12,15 @@
 | 
			
		||||
 | 
			
		||||
#include "msi.h"
 | 
			
		||||
#include "rtp.h"
 | 
			
		||||
#include "toxav_hacks.h"
 | 
			
		||||
 | 
			
		||||
#include "../toxcore/Messenger.h"
 | 
			
		||||
#include "../toxcore/ccompat.h"
 | 
			
		||||
#include "../toxcore/logger.h"
 | 
			
		||||
#include "../toxcore/mono_time.h"
 | 
			
		||||
#include "../toxcore/net_crypto.h"
 | 
			
		||||
#include "../toxcore/network.h"
 | 
			
		||||
#include "../toxcore/tox.h"
 | 
			
		||||
#include "../toxcore/tox_private.h"
 | 
			
		||||
#include "../toxcore/tox_struct.h"
 | 
			
		||||
#include "../toxcore/util.h"
 | 
			
		||||
 | 
			
		||||
@@ -36,7 +40,12 @@
 | 
			
		||||
// iteration interval that is used when no call is active
 | 
			
		||||
#define IDLE_ITERATION_INTERVAL_MS 200
 | 
			
		||||
 | 
			
		||||
typedef struct ToxAVCall {
 | 
			
		||||
#ifndef TOXAV_CALL_DEFINED
 | 
			
		||||
#define TOXAV_CALL_DEFINED
 | 
			
		||||
typedef struct ToxAVCall ToxAVCall;
 | 
			
		||||
#endif /* TOXAV_CALL_DEFINED */
 | 
			
		||||
 | 
			
		||||
struct ToxAVCall {
 | 
			
		||||
    ToxAV *av;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_t mutex_audio[1];
 | 
			
		||||
@@ -63,7 +72,7 @@ typedef struct ToxAVCall {
 | 
			
		||||
 | 
			
		||||
    struct ToxAVCall *prev;
 | 
			
		||||
    struct ToxAVCall *next;
 | 
			
		||||
} ToxAVCall;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Decode time statistics */
 | 
			
		||||
typedef struct DecodeTimeStats {
 | 
			
		||||
@@ -79,8 +88,8 @@ typedef struct DecodeTimeStats {
 | 
			
		||||
} DecodeTimeStats;
 | 
			
		||||
 | 
			
		||||
struct ToxAV {
 | 
			
		||||
    Logger *log;
 | 
			
		||||
    Tox *tox;
 | 
			
		||||
    Messenger *m;
 | 
			
		||||
    MSISession *msi;
 | 
			
		||||
 | 
			
		||||
    /* Two-way storage: first is array of calls and second is list of calls with head and tail */
 | 
			
		||||
@@ -111,8 +120,8 @@ struct ToxAV {
 | 
			
		||||
    /* keep track of decode times for audio and video */
 | 
			
		||||
    DecodeTimeStats audio_stats;
 | 
			
		||||
    DecodeTimeStats video_stats;
 | 
			
		||||
    /** ToxAV's own mono_time instance */
 | 
			
		||||
    Mono_Time *toxav_mono_time;
 | 
			
		||||
 | 
			
		||||
    Mono_Time *toxav_mono_time; // ToxAV's own mono_time instance
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data);
 | 
			
		||||
@@ -127,11 +136,55 @@ static bool audio_bit_rate_invalid(uint32_t bit_rate);
 | 
			
		||||
static bool video_bit_rate_invalid(uint32_t bit_rate);
 | 
			
		||||
static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state);
 | 
			
		||||
static ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *error);
 | 
			
		||||
static ToxAVCall *call_get(ToxAV *av, uint32_t friend_number);
 | 
			
		||||
static ToxAVCall *call_remove(ToxAVCall *call);
 | 
			
		||||
static bool call_prepare_transmission(ToxAVCall *call);
 | 
			
		||||
static void call_kill_transmission(ToxAVCall *call);
 | 
			
		||||
 | 
			
		||||
MSISession *tox_av_msi_get(const ToxAV *av)
 | 
			
		||||
{
 | 
			
		||||
    if (av == nullptr) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return av->msi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ToxAVCall *call_get(ToxAV *av, uint32_t friend_number)
 | 
			
		||||
{
 | 
			
		||||
    if (av == nullptr) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Assumes mutex locked */
 | 
			
		||||
    if (av->calls == nullptr || av->calls_tail < friend_number) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return av->calls[friend_number];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTPSession *rtp_session_get(ToxAVCall *call, int payload_type)
 | 
			
		||||
{
 | 
			
		||||
    if (call == nullptr) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (payload_type == RTP_TYPE_VIDEO) {
 | 
			
		||||
        return call->video_rtp;
 | 
			
		||||
    } else {
 | 
			
		||||
        return call->audio_rtp;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BWController *bwc_controller_get(const ToxAVCall *call)
 | 
			
		||||
{
 | 
			
		||||
    if (call == nullptr) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return call->bwc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief initialize d with default values
 | 
			
		||||
 * @param d struct to be initialized, must not be nullptr
 | 
			
		||||
@@ -155,33 +208,26 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error)
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO(iphydf): Don't rely on toxcore internals.
 | 
			
		||||
    Messenger *m;
 | 
			
		||||
    m = tox->m;
 | 
			
		||||
 | 
			
		||||
    if (m->msi_packet != nullptr) {
 | 
			
		||||
        rc = TOXAV_ERR_NEW_MULTIPLE;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    av = (ToxAV *)calloc(1, sizeof(ToxAV));
 | 
			
		||||
 | 
			
		||||
    if (av == nullptr) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "Allocation failed!");
 | 
			
		||||
        rc = TOXAV_ERR_NEW_MALLOC;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (create_recursive_mutex(av->mutex) != 0) {
 | 
			
		||||
        LOGGER_WARNING(m->log, "Mutex creation failed!");
 | 
			
		||||
        rc = TOXAV_ERR_NEW_MALLOC;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    av->log = tox->m->log;
 | 
			
		||||
    av->tox = tox;
 | 
			
		||||
    av->m = m;
 | 
			
		||||
    av->msi = msi_new(av->log, av->tox);
 | 
			
		||||
 | 
			
		||||
    rtp_allow_receiving(av->tox);
 | 
			
		||||
    bwc_allow_receiving(av->tox);
 | 
			
		||||
 | 
			
		||||
    av->toxav_mono_time = mono_time_new(tox->sys.mem, nullptr, nullptr);
 | 
			
		||||
    av->msi = msi_new(av->m);
 | 
			
		||||
 | 
			
		||||
    if (av->msi == nullptr) {
 | 
			
		||||
        pthread_mutex_destroy(av->mutex);
 | 
			
		||||
@@ -193,6 +239,9 @@ ToxAV *toxav_new(Tox *tox, Toxav_Err_New *error)
 | 
			
		||||
    init_decode_time_stats(&av->video_stats);
 | 
			
		||||
    av->msi->av = av;
 | 
			
		||||
 | 
			
		||||
    // save ToxAV object into toxcore
 | 
			
		||||
    tox_set_av_object(av->tox, av);
 | 
			
		||||
 | 
			
		||||
    msi_callback_invite(av->msi, callback_invite);
 | 
			
		||||
    msi_callback_start(av->msi, callback_start);
 | 
			
		||||
    msi_callback_end(av->msi, callback_end);
 | 
			
		||||
@@ -207,12 +256,15 @@ RETURN:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (rc != TOXAV_ERR_NEW_OK) {
 | 
			
		||||
        free(av);
 | 
			
		||||
        av = nullptr;
 | 
			
		||||
        if (av != nullptr) {
 | 
			
		||||
            free(av);
 | 
			
		||||
            av = nullptr;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return av;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void toxav_kill(ToxAV *av)
 | 
			
		||||
{
 | 
			
		||||
    if (av == nullptr) {
 | 
			
		||||
@@ -221,8 +273,16 @@ void toxav_kill(ToxAV *av)
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(av->mutex);
 | 
			
		||||
 | 
			
		||||
    // unregister callbacks
 | 
			
		||||
    for (uint8_t i = PACKET_ID_RANGE_LOSSY_AV_START; i <= PACKET_ID_RANGE_LOSSY_AV_END; ++i) {
 | 
			
		||||
        tox_callback_friend_lossy_packet_per_pktid(av->tox, nullptr, i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtp_stop_receiving(av->tox);
 | 
			
		||||
    bwc_stop_receiving(av->tox);
 | 
			
		||||
 | 
			
		||||
    /* To avoid possible deadlocks */
 | 
			
		||||
    while (av->msi != nullptr && msi_kill(av->msi, av->m->log) != 0) {
 | 
			
		||||
    while (av->msi != nullptr && msi_kill(av->log, av->tox, av->msi) != 0) {
 | 
			
		||||
        pthread_mutex_unlock(av->mutex);
 | 
			
		||||
        pthread_mutex_lock(av->mutex);
 | 
			
		||||
    }
 | 
			
		||||
@@ -243,13 +303,22 @@ void toxav_kill(ToxAV *av)
 | 
			
		||||
    pthread_mutex_unlock(av->mutex);
 | 
			
		||||
    pthread_mutex_destroy(av->mutex);
 | 
			
		||||
 | 
			
		||||
    // set ToxAV object to NULL in toxcore, to signal ToxAV has been shutdown
 | 
			
		||||
    tox_set_av_object(av->tox, nullptr);
 | 
			
		||||
 | 
			
		||||
    free(av);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Tox *toxav_get_tox(const ToxAV *av)
 | 
			
		||||
{
 | 
			
		||||
    return av->tox;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Logger *toxav_get_logger(const ToxAV *av)
 | 
			
		||||
{
 | 
			
		||||
    return av->log;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t toxav_audio_iteration_interval(const ToxAV *av)
 | 
			
		||||
{
 | 
			
		||||
    return av->calls != nullptr ? av->audio_stats.interval : IDLE_ITERATION_INTERVAL_MS;
 | 
			
		||||
@@ -276,10 +345,11 @@ uint32_t toxav_iteration_interval(const ToxAV *av)
 | 
			
		||||
static void calc_interval(ToxAV *av, DecodeTimeStats *stats, int32_t frame_time, uint64_t start_time)
 | 
			
		||||
{
 | 
			
		||||
    stats->interval = frame_time < stats->average ? 0 : (frame_time - stats->average);
 | 
			
		||||
    stats->total += current_time_monotonic(av->m->mono_time) - start_time;
 | 
			
		||||
    stats->total += current_time_monotonic(av->toxav_mono_time) - start_time;
 | 
			
		||||
 | 
			
		||||
    if (++stats->count == 3) {
 | 
			
		||||
        stats->average = stats->total / 3 + 5; /* NOTE: Magic Offset for precision */
 | 
			
		||||
        /* NOTE: Magic Offset for precision */
 | 
			
		||||
        stats->average = stats->total / 3 + 5;
 | 
			
		||||
        stats->count = 0;
 | 
			
		||||
        stats->total = 0;
 | 
			
		||||
    }
 | 
			
		||||
@@ -300,7 +370,6 @@ static void iterate_common(ToxAV *av, bool audio)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const uint64_t start = current_time_monotonic(av->toxav_mono_time);
 | 
			
		||||
    // time until the first audio or video frame is over
 | 
			
		||||
    int32_t frame_time = IDLE_ITERATION_INTERVAL_MS;
 | 
			
		||||
 | 
			
		||||
    for (ToxAVCall *i = av->calls[av->calls_head]; i != nullptr; i = i->next) {
 | 
			
		||||
@@ -311,6 +380,15 @@ static void iterate_common(ToxAV *av, bool audio)
 | 
			
		||||
        pthread_mutex_lock(i->toxav_call_mutex);
 | 
			
		||||
        pthread_mutex_unlock(av->mutex);
 | 
			
		||||
 | 
			
		||||
        const uint32_t fid = i->friend_number;
 | 
			
		||||
        const bool is_offline = check_peer_offline_status(av->log, av->tox, i->msi_call->session, fid);
 | 
			
		||||
 | 
			
		||||
        if (is_offline) {
 | 
			
		||||
            pthread_mutex_unlock(i->toxav_call_mutex);
 | 
			
		||||
            pthread_mutex_lock(av->mutex);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (audio) {
 | 
			
		||||
            ac_iterate(i->audio);
 | 
			
		||||
 | 
			
		||||
@@ -329,8 +407,6 @@ static void iterate_common(ToxAV *av, bool audio)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const uint32_t fid = i->friend_number;
 | 
			
		||||
 | 
			
		||||
        pthread_mutex_unlock(i->toxav_call_mutex);
 | 
			
		||||
        pthread_mutex_lock(av->mutex);
 | 
			
		||||
 | 
			
		||||
@@ -342,8 +418,10 @@ static void iterate_common(ToxAV *av, bool audio)
 | 
			
		||||
 | 
			
		||||
    DecodeTimeStats *stats = audio ? &av->audio_stats : &av->video_stats;
 | 
			
		||||
    calc_interval(av, stats, frame_time, start);
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(av->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void toxav_audio_iterate(ToxAV *av)
 | 
			
		||||
{
 | 
			
		||||
    iterate_common(av, true);
 | 
			
		||||
@@ -388,7 +466,7 @@ bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint
 | 
			
		||||
    call->previous_self_capabilities |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0;
 | 
			
		||||
    call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 0;
 | 
			
		||||
 | 
			
		||||
    if (msi_invite(av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) {
 | 
			
		||||
    if (msi_invite(av->log, av->msi, &call->msi_call, friend_number, call->previous_self_capabilities) != 0) {
 | 
			
		||||
        call_remove(call);
 | 
			
		||||
        rc = TOXAV_ERR_CALL_SYNC;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
@@ -405,6 +483,7 @@ RETURN:
 | 
			
		||||
 | 
			
		||||
    return rc == TOXAV_ERR_CALL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(av->mutex);
 | 
			
		||||
@@ -412,6 +491,7 @@ void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data)
 | 
			
		||||
    av->ccb_user_data = user_data;
 | 
			
		||||
    pthread_mutex_unlock(av->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
 | 
			
		||||
                  Toxav_Err_Answer *error)
 | 
			
		||||
{
 | 
			
		||||
@@ -420,7 +500,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui
 | 
			
		||||
    Toxav_Err_Answer rc = TOXAV_ERR_ANSWER_OK;
 | 
			
		||||
    ToxAVCall *call;
 | 
			
		||||
 | 
			
		||||
    if (!m_friend_exists(av->m, friend_number)) {
 | 
			
		||||
    if (!tox_friend_exists(av->tox, friend_number)) {
 | 
			
		||||
        rc = TOXAV_ERR_ANSWER_FRIEND_NOT_FOUND;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
@@ -452,7 +532,7 @@ bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, ui
 | 
			
		||||
    call->previous_self_capabilities |= audio_bit_rate > 0 ? MSI_CAP_S_AUDIO : 0;
 | 
			
		||||
    call->previous_self_capabilities |= video_bit_rate > 0 ? MSI_CAP_S_VIDEO : 0;
 | 
			
		||||
 | 
			
		||||
    if (msi_answer(call->msi_call, call->previous_self_capabilities) != 0) {
 | 
			
		||||
    if (msi_answer(av->log, call->msi_call, call->previous_self_capabilities) != 0) {
 | 
			
		||||
        rc = TOXAV_ERR_ANSWER_SYNC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -465,6 +545,7 @@ RETURN:
 | 
			
		||||
 | 
			
		||||
    return rc == TOXAV_ERR_ANSWER_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(av->mutex);
 | 
			
		||||
@@ -472,6 +553,7 @@ void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *u
 | 
			
		||||
    av->scb_user_data = user_data;
 | 
			
		||||
    pthread_mutex_unlock(av->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Toxav_Err_Call_Control call_control_handle_resume(const ToxAVCall *call)
 | 
			
		||||
{
 | 
			
		||||
    /* Only act if paused and had media transfer active before */
 | 
			
		||||
@@ -479,12 +561,13 @@ static Toxav_Err_Call_Control call_control_handle_resume(const ToxAVCall *call)
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (msi_change_capabilities(call->msi_call, call->previous_self_capabilities) == -1) {
 | 
			
		||||
    if (msi_change_capabilities(call->av->log, call->msi_call,
 | 
			
		||||
                                call->previous_self_capabilities) == -1) {
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_SYNC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtp_allow_receiving(call->audio_rtp);
 | 
			
		||||
    rtp_allow_receiving(call->video_rtp);
 | 
			
		||||
    rtp_allow_receiving_mark(call->audio_rtp);
 | 
			
		||||
    rtp_allow_receiving_mark(call->video_rtp);
 | 
			
		||||
 | 
			
		||||
    return TOXAV_ERR_CALL_CONTROL_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -497,12 +580,12 @@ static Toxav_Err_Call_Control call_control_handle_pause(ToxAVCall *call)
 | 
			
		||||
 | 
			
		||||
    call->previous_self_capabilities = call->msi_call->self_capabilities;
 | 
			
		||||
 | 
			
		||||
    if (msi_change_capabilities(call->msi_call, 0) == -1) {
 | 
			
		||||
    if (msi_change_capabilities(call->av->log, call->msi_call, 0) == -1) {
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_SYNC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtp_stop_receiving(call->audio_rtp);
 | 
			
		||||
    rtp_stop_receiving(call->video_rtp);
 | 
			
		||||
    rtp_stop_receiving_mark(call->audio_rtp);
 | 
			
		||||
    rtp_stop_receiving_mark(call->video_rtp);
 | 
			
		||||
 | 
			
		||||
    return TOXAV_ERR_CALL_CONTROL_OK;
 | 
			
		||||
}
 | 
			
		||||
@@ -511,7 +594,7 @@ static Toxav_Err_Call_Control call_control_handle_cancel(ToxAVCall *call)
 | 
			
		||||
    /* Hang up */
 | 
			
		||||
    pthread_mutex_lock(call->toxav_call_mutex);
 | 
			
		||||
 | 
			
		||||
    if (msi_hangup(call->msi_call) != 0) {
 | 
			
		||||
    if (msi_hangup(call->av->log, call->msi_call) != 0) {
 | 
			
		||||
        pthread_mutex_unlock(call->toxav_call_mutex);
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_SYNC;
 | 
			
		||||
    }
 | 
			
		||||
@@ -531,13 +614,13 @@ static Toxav_Err_Call_Control call_control_handle_mute_audio(const ToxAVCall *ca
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (msi_change_capabilities(call->msi_call, call->
 | 
			
		||||
    if (msi_change_capabilities(call->av->log, call->msi_call, call->
 | 
			
		||||
                                msi_call->self_capabilities ^ MSI_CAP_R_AUDIO) == -1) {
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_SYNC;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtp_stop_receiving(call->audio_rtp);
 | 
			
		||||
    rtp_stop_receiving_mark(call->audio_rtp);
 | 
			
		||||
    return TOXAV_ERR_CALL_CONTROL_OK;
 | 
			
		||||
}
 | 
			
		||||
static Toxav_Err_Call_Control call_control_handle_unmute_audio(const ToxAVCall *call)
 | 
			
		||||
@@ -546,12 +629,12 @@ static Toxav_Err_Call_Control call_control_handle_unmute_audio(const ToxAVCall *
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (msi_change_capabilities(call->msi_call, call->
 | 
			
		||||
    if (msi_change_capabilities(call->av->log, call->msi_call, call->
 | 
			
		||||
                                msi_call->self_capabilities | MSI_CAP_R_AUDIO) == -1) {
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_SYNC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtp_allow_receiving(call->audio_rtp);
 | 
			
		||||
    rtp_allow_receiving_mark(call->audio_rtp);
 | 
			
		||||
    return TOXAV_ERR_CALL_CONTROL_OK;
 | 
			
		||||
}
 | 
			
		||||
static Toxav_Err_Call_Control call_control_handle_hide_video(const ToxAVCall *call)
 | 
			
		||||
@@ -560,12 +643,12 @@ static Toxav_Err_Call_Control call_control_handle_hide_video(const ToxAVCall *ca
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (msi_change_capabilities(call->msi_call, call->
 | 
			
		||||
    if (msi_change_capabilities(call->av->log, call->msi_call, call->
 | 
			
		||||
                                msi_call->self_capabilities ^ MSI_CAP_R_VIDEO) == -1) {
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_SYNC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtp_stop_receiving(call->video_rtp);
 | 
			
		||||
    rtp_stop_receiving_mark(call->video_rtp);
 | 
			
		||||
    return TOXAV_ERR_CALL_CONTROL_OK;
 | 
			
		||||
}
 | 
			
		||||
static Toxav_Err_Call_Control call_control_handle_show_video(const ToxAVCall *call)
 | 
			
		||||
@@ -574,12 +657,12 @@ static Toxav_Err_Call_Control call_control_handle_show_video(const ToxAVCall *ca
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_INVALID_TRANSITION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (msi_change_capabilities(call->msi_call, call->
 | 
			
		||||
    if (msi_change_capabilities(call->av->log, call->msi_call, call->
 | 
			
		||||
                                msi_call->self_capabilities | MSI_CAP_R_VIDEO) == -1) {
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_SYNC;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtp_allow_receiving(call->video_rtp);
 | 
			
		||||
    rtp_allow_receiving_mark(call->video_rtp);
 | 
			
		||||
    return TOXAV_ERR_CALL_CONTROL_OK;
 | 
			
		||||
}
 | 
			
		||||
static Toxav_Err_Call_Control call_control_handle(ToxAVCall *call, Toxav_Call_Control control)
 | 
			
		||||
@@ -611,7 +694,7 @@ static Toxav_Err_Call_Control call_control_handle(ToxAVCall *call, Toxav_Call_Co
 | 
			
		||||
}
 | 
			
		||||
static Toxav_Err_Call_Control call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control control)
 | 
			
		||||
{
 | 
			
		||||
    if (!m_friend_exists(av->m, friend_number)) {
 | 
			
		||||
    if (!tox_friend_exists(av->tox, friend_number)) {
 | 
			
		||||
        return TOXAV_ERR_CALL_CONTROL_FRIEND_NOT_FOUND;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -637,13 +720,14 @@ bool toxav_call_control(ToxAV *av, uint32_t friend_number, Toxav_Call_Control co
 | 
			
		||||
 | 
			
		||||
    return rc == TOXAV_ERR_CALL_CONTROL_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_rate,
 | 
			
		||||
                              Toxav_Err_Bit_Rate_Set *error)
 | 
			
		||||
{
 | 
			
		||||
    Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK;
 | 
			
		||||
    ToxAVCall *call;
 | 
			
		||||
 | 
			
		||||
    if (!m_friend_exists(av->m, friend_number)) {
 | 
			
		||||
    if (!tox_friend_exists(av->tox, friend_number)) {
 | 
			
		||||
        rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
@@ -662,14 +746,14 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(av->m->log, "Setting new audio bitrate to: %d", bit_rate);
 | 
			
		||||
    LOGGER_DEBUG(av->log, "Setting new audio bitrate to: %d", bit_rate);
 | 
			
		||||
 | 
			
		||||
    if (call->audio_bit_rate == bit_rate) {
 | 
			
		||||
        LOGGER_DEBUG(av->m->log, "Audio bitrate already set to: %d", bit_rate);
 | 
			
		||||
        LOGGER_DEBUG(av->log, "Audio bitrate already set to: %d", bit_rate);
 | 
			
		||||
    } else if (bit_rate == 0) {
 | 
			
		||||
        LOGGER_DEBUG(av->m->log, "Turned off audio sending");
 | 
			
		||||
        LOGGER_DEBUG(av->log, "Turned off audio sending");
 | 
			
		||||
 | 
			
		||||
        if (msi_change_capabilities(call->msi_call, call->msi_call->
 | 
			
		||||
        if (msi_change_capabilities(av->log, call->msi_call, call->msi_call->
 | 
			
		||||
                                    self_capabilities ^ MSI_CAP_S_AUDIO) != 0) {
 | 
			
		||||
            pthread_mutex_unlock(av->mutex);
 | 
			
		||||
            rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
 | 
			
		||||
@@ -682,10 +766,10 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
 | 
			
		||||
        pthread_mutex_lock(call->toxav_call_mutex);
 | 
			
		||||
 | 
			
		||||
        if (call->audio_bit_rate == 0) {
 | 
			
		||||
            LOGGER_DEBUG(av->m->log, "Turned on audio sending");
 | 
			
		||||
            LOGGER_DEBUG(av->log, "Turned on audio sending");
 | 
			
		||||
 | 
			
		||||
            /* The audio has been turned off before this */
 | 
			
		||||
            if (msi_change_capabilities(call->msi_call, call->
 | 
			
		||||
            if (msi_change_capabilities(av->log, call->msi_call, call->
 | 
			
		||||
                                        msi_call->self_capabilities | MSI_CAP_S_AUDIO) != 0) {
 | 
			
		||||
                pthread_mutex_unlock(call->toxav_call_mutex);
 | 
			
		||||
                pthread_mutex_unlock(av->mutex);
 | 
			
		||||
@@ -693,7 +777,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
 | 
			
		||||
                goto RETURN;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            LOGGER_DEBUG(av->m->log, "Set new audio bit rate %d", bit_rate);
 | 
			
		||||
            LOGGER_DEBUG(av->log, "Set new audio bit rate %d", bit_rate);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        call->audio_bit_rate = bit_rate;
 | 
			
		||||
@@ -709,13 +793,14 @@ RETURN:
 | 
			
		||||
 | 
			
		||||
    return rc == TOXAV_ERR_BIT_RATE_SET_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_rate,
 | 
			
		||||
                              Toxav_Err_Bit_Rate_Set *error)
 | 
			
		||||
{
 | 
			
		||||
    Toxav_Err_Bit_Rate_Set rc = TOXAV_ERR_BIT_RATE_SET_OK;
 | 
			
		||||
    ToxAVCall *call;
 | 
			
		||||
 | 
			
		||||
    if (!m_friend_exists(av->m, friend_number)) {
 | 
			
		||||
    if (!tox_friend_exists(av->tox, friend_number)) {
 | 
			
		||||
        rc = TOXAV_ERR_BIT_RATE_SET_FRIEND_NOT_FOUND;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
@@ -734,15 +819,15 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(av->m->log, "Setting new video bitrate to: %d", bit_rate);
 | 
			
		||||
    LOGGER_DEBUG(av->log, "Setting new video bitrate to: %d", bit_rate);
 | 
			
		||||
 | 
			
		||||
    if (call->video_bit_rate == bit_rate) {
 | 
			
		||||
        LOGGER_DEBUG(av->m->log, "Video bitrate already set to: %d", bit_rate);
 | 
			
		||||
        LOGGER_DEBUG(av->log, "Video bitrate already set to: %d", bit_rate);
 | 
			
		||||
    } else if (bit_rate == 0) {
 | 
			
		||||
        LOGGER_DEBUG(av->m->log, "Turned off video sending");
 | 
			
		||||
        LOGGER_DEBUG(av->log, "Turned off video sending");
 | 
			
		||||
 | 
			
		||||
        /* Video sending is turned off; notify peer */
 | 
			
		||||
        if (msi_change_capabilities(call->msi_call, call->msi_call->
 | 
			
		||||
        if (msi_change_capabilities(av->log, call->msi_call, call->msi_call->
 | 
			
		||||
                                    self_capabilities ^ MSI_CAP_S_VIDEO) != 0) {
 | 
			
		||||
            pthread_mutex_unlock(av->mutex);
 | 
			
		||||
            rc = TOXAV_ERR_BIT_RATE_SET_SYNC;
 | 
			
		||||
@@ -754,10 +839,10 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
 | 
			
		||||
        pthread_mutex_lock(call->toxav_call_mutex);
 | 
			
		||||
 | 
			
		||||
        if (call->video_bit_rate == 0) {
 | 
			
		||||
            LOGGER_DEBUG(av->m->log, "Turned on video sending");
 | 
			
		||||
            LOGGER_DEBUG(av->log, "Turned on video sending");
 | 
			
		||||
 | 
			
		||||
            /* The video has been turned off before this */
 | 
			
		||||
            if (msi_change_capabilities(call->msi_call, call->
 | 
			
		||||
            if (msi_change_capabilities(av->log, call->msi_call, call->
 | 
			
		||||
                                        msi_call->self_capabilities | MSI_CAP_S_VIDEO) != 0) {
 | 
			
		||||
                pthread_mutex_unlock(call->toxav_call_mutex);
 | 
			
		||||
                pthread_mutex_unlock(av->mutex);
 | 
			
		||||
@@ -765,7 +850,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
 | 
			
		||||
                goto RETURN;
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            LOGGER_DEBUG(av->m->log, "Set new video bit rate %d", bit_rate);
 | 
			
		||||
            LOGGER_DEBUG(av->log, "Set new video bit rate %d", bit_rate);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        call->video_bit_rate = bit_rate;
 | 
			
		||||
@@ -781,6 +866,7 @@ RETURN:
 | 
			
		||||
 | 
			
		||||
    return rc == TOXAV_ERR_BIT_RATE_SET_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(av->mutex);
 | 
			
		||||
@@ -788,6 +874,7 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback,
 | 
			
		||||
    av->abcb_user_data = user_data;
 | 
			
		||||
    pthread_mutex_unlock(av->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback, void *user_data)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(av->mutex);
 | 
			
		||||
@@ -795,13 +882,14 @@ void toxav_callback_video_bit_rate(ToxAV *av, toxav_video_bit_rate_cb *callback,
 | 
			
		||||
    av->vbcb_user_data = user_data;
 | 
			
		||||
    pthread_mutex_unlock(av->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count,
 | 
			
		||||
                            uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error)
 | 
			
		||||
{
 | 
			
		||||
    Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK;
 | 
			
		||||
    ToxAVCall *call;
 | 
			
		||||
 | 
			
		||||
    if (!m_friend_exists(av->m, friend_number)) {
 | 
			
		||||
    if (!tox_friend_exists(av->tox, friend_number)) {
 | 
			
		||||
        rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
@@ -859,14 +947,14 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pc
 | 
			
		||||
                                    dest + sizeof(sampling_rate), dest_size - sizeof(sampling_rate));
 | 
			
		||||
 | 
			
		||||
        if (vrc < 0) {
 | 
			
		||||
            LOGGER_WARNING(av->m->log, "Failed to encode frame %s", opus_strerror(vrc));
 | 
			
		||||
            LOGGER_WARNING(av->log, "Failed to encode frame %s", opus_strerror(vrc));
 | 
			
		||||
            pthread_mutex_unlock(call->mutex_audio);
 | 
			
		||||
            rc = TOXAV_ERR_SEND_FRAME_INVALID;
 | 
			
		||||
            goto RETURN;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (rtp_send_data(call->audio_rtp, dest, vrc + sizeof(sampling_rate), false, av->m->log) != 0) {
 | 
			
		||||
            LOGGER_WARNING(av->m->log, "Failed to send audio packet");
 | 
			
		||||
        if (rtp_send_data(av->log, call->audio_rtp, dest, vrc + sizeof(sampling_rate), false) != 0) {
 | 
			
		||||
            LOGGER_WARNING(av->log, "Failed to send audio packet");
 | 
			
		||||
            rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -882,7 +970,7 @@ RETURN:
 | 
			
		||||
    return rc == TOXAV_ERR_SEND_FRAME_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Toxav_Err_Send_Frame send_frames(const Logger *log, ToxAVCall *call)
 | 
			
		||||
static Toxav_Err_Send_Frame send_frames(const ToxAV *av, ToxAVCall *call)
 | 
			
		||||
{
 | 
			
		||||
    vpx_codec_iter_t iter = nullptr;
 | 
			
		||||
 | 
			
		||||
@@ -900,20 +988,15 @@ static Toxav_Err_Send_Frame send_frames(const Logger *log, ToxAVCall *call)
 | 
			
		||||
        const uint32_t frame_length_in_bytes = pkt->data.frame.sz;
 | 
			
		||||
 | 
			
		||||
        const int res = rtp_send_data(
 | 
			
		||||
                            av->log,
 | 
			
		||||
                            call->video_rtp,
 | 
			
		||||
                            (const uint8_t *)pkt->data.frame.buf,
 | 
			
		||||
                            frame_length_in_bytes,
 | 
			
		||||
                            is_keyframe,
 | 
			
		||||
                            log);
 | 
			
		||||
 | 
			
		||||
        LOGGER_DEBUG(log, "+ _sending_FRAME_TYPE_==%s bytes=%d frame_len=%d", is_keyframe ? "K" : ".",
 | 
			
		||||
                     (int)pkt->data.frame.sz, (int)frame_length_in_bytes);
 | 
			
		||||
        const uint8_t *const buf = (const uint8_t *)pkt->data.frame.buf;
 | 
			
		||||
        LOGGER_DEBUG(log, "+ _sending_FRAME_ b0=%d b1=%d", buf[0], buf[1]);
 | 
			
		||||
                            is_keyframe);
 | 
			
		||||
 | 
			
		||||
        if (res < 0) {
 | 
			
		||||
            char *netstrerror = net_new_strerror(net_error());
 | 
			
		||||
            LOGGER_WARNING(log, "Could not send video frame: %s", netstrerror);
 | 
			
		||||
            LOGGER_WARNING(av->log, "Could not send video frame: %s", netstrerror);
 | 
			
		||||
            net_kill_strerror(netstrerror);
 | 
			
		||||
            return TOXAV_ERR_SEND_FRAME_RTP_FAILED;
 | 
			
		||||
        }
 | 
			
		||||
@@ -930,7 +1013,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
 | 
			
		||||
 | 
			
		||||
    int vpx_encode_flags = 0;
 | 
			
		||||
 | 
			
		||||
    if (!m_friend_exists(av->m, friend_number)) {
 | 
			
		||||
    if (!tox_friend_exists(av->tox, friend_number)) {
 | 
			
		||||
        rc = TOXAV_ERR_SEND_FRAME_FRIEND_NOT_FOUND;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
@@ -965,7 +1048,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (vc_reconfigure_encoder(call->video, call->video_bit_rate * 1000, width, height, -1) != 0) {
 | 
			
		||||
    if (vc_reconfigure_encoder(call->video, call->video_bit_rate, width, height, -1) != 0) {
 | 
			
		||||
        pthread_mutex_unlock(call->mutex_video);
 | 
			
		||||
        rc = TOXAV_ERR_SEND_FRAME_INVALID;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
@@ -974,13 +1057,13 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
 | 
			
		||||
    if (call->video_rtp->ssrc < VIDEO_SEND_X_KEYFRAMES_FIRST) {
 | 
			
		||||
        // Key frame flag for first frames
 | 
			
		||||
        vpx_encode_flags = VPX_EFLAG_FORCE_KF;
 | 
			
		||||
        LOGGER_DEBUG(av->m->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc);
 | 
			
		||||
        LOGGER_DEBUG(av->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc);
 | 
			
		||||
 | 
			
		||||
        ++call->video_rtp->ssrc;
 | 
			
		||||
    } else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) {
 | 
			
		||||
        // normal keyframe placement
 | 
			
		||||
        vpx_encode_flags = 0;
 | 
			
		||||
        LOGGER_DEBUG(av->m->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc);
 | 
			
		||||
        LOGGER_DEBUG(av->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc);
 | 
			
		||||
 | 
			
		||||
        ++call->video_rtp->ssrc;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1009,7 +1092,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
 | 
			
		||||
 | 
			
		||||
        if (vrc != VPX_CODEC_OK) {
 | 
			
		||||
            pthread_mutex_unlock(call->mutex_video);
 | 
			
		||||
            LOGGER_ERROR(av->m->log, "Could not encode video frame: %s", vpx_codec_err_to_string(vrc));
 | 
			
		||||
            LOGGER_ERROR(av->log, "Could not encode video frame: %s", vpx_codec_err_to_string(vrc));
 | 
			
		||||
            rc = TOXAV_ERR_SEND_FRAME_INVALID;
 | 
			
		||||
            goto RETURN;
 | 
			
		||||
        }
 | 
			
		||||
@@ -1017,7 +1100,7 @@ bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, u
 | 
			
		||||
 | 
			
		||||
    ++call->video->frame_counter;
 | 
			
		||||
 | 
			
		||||
    rc = send_frames(av->m->log, call);
 | 
			
		||||
    rc = send_frames(av, call);
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(call->mutex_video);
 | 
			
		||||
 | 
			
		||||
@@ -1063,7 +1146,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
 | 
			
		||||
    ToxAVCall *call = (ToxAVCall *)user_data;
 | 
			
		||||
    assert(call != nullptr);
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", (double)loss * 100);
 | 
			
		||||
    LOGGER_DEBUG(call->av->log, "Reported loss of %f%%", (double)loss * 100);
 | 
			
		||||
 | 
			
		||||
    /* if less than 10% data loss we do nothing! */
 | 
			
		||||
    if (loss < 0.1F) {
 | 
			
		||||
@@ -1075,7 +1158,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
 | 
			
		||||
    if (call->video_bit_rate != 0) {
 | 
			
		||||
        if (call->av->vbcb == nullptr) {
 | 
			
		||||
            pthread_mutex_unlock(call->av->mutex);
 | 
			
		||||
            LOGGER_WARNING(call->av->m->log, "No callback to report loss on");
 | 
			
		||||
            LOGGER_WARNING(call->av->log, "No callback to report loss on");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1085,7 +1168,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
 | 
			
		||||
    } else if (call->audio_bit_rate != 0) {
 | 
			
		||||
        if (call->av->abcb == nullptr) {
 | 
			
		||||
            pthread_mutex_unlock(call->av->mutex);
 | 
			
		||||
            LOGGER_WARNING(call->av->m->log, "No callback to report loss on");
 | 
			
		||||
            LOGGER_WARNING(call->av->log, "No callback to report loss on");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1096,6 +1179,7 @@ static void callback_bwc(BWController *bwc, uint32_t friend_number, float loss,
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(call->av->mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int callback_invite(void *object, MSICall *call)
 | 
			
		||||
{
 | 
			
		||||
    ToxAV *toxav = (ToxAV *)object;
 | 
			
		||||
@@ -1104,7 +1188,7 @@ static int callback_invite(void *object, MSICall *call)
 | 
			
		||||
    ToxAVCall *av_call = call_new(toxav, call->friend_number, nullptr);
 | 
			
		||||
 | 
			
		||||
    if (av_call == nullptr) {
 | 
			
		||||
        LOGGER_WARNING(toxav->m->log, "Failed to initialize call...");
 | 
			
		||||
        LOGGER_WARNING(toxav->log, "Failed to initialize call...");
 | 
			
		||||
        pthread_mutex_unlock(toxav->mutex);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1124,6 +1208,7 @@ static int callback_invite(void *object, MSICall *call)
 | 
			
		||||
    pthread_mutex_unlock(toxav->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int callback_start(void *object, MSICall *call)
 | 
			
		||||
{
 | 
			
		||||
    ToxAV *toxav = (ToxAV *)object;
 | 
			
		||||
@@ -1152,6 +1237,7 @@ static int callback_start(void *object, MSICall *call)
 | 
			
		||||
    pthread_mutex_unlock(toxav->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int callback_end(void *object, MSICall *call)
 | 
			
		||||
{
 | 
			
		||||
    ToxAV *toxav = (ToxAV *)object;
 | 
			
		||||
@@ -1167,6 +1253,7 @@ static int callback_end(void *object, MSICall *call)
 | 
			
		||||
    pthread_mutex_unlock(toxav->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int callback_error(void *object, MSICall *call)
 | 
			
		||||
{
 | 
			
		||||
    ToxAV *toxav = (ToxAV *)object;
 | 
			
		||||
@@ -1182,21 +1269,22 @@ static int callback_error(void *object, MSICall *call)
 | 
			
		||||
    pthread_mutex_unlock(toxav->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int callback_capabilites(void *object, MSICall *call)
 | 
			
		||||
{
 | 
			
		||||
    ToxAV *toxav = (ToxAV *)object;
 | 
			
		||||
    pthread_mutex_lock(toxav->mutex);
 | 
			
		||||
 | 
			
		||||
    if ((call->peer_capabilities & MSI_CAP_S_AUDIO) != 0) {
 | 
			
		||||
        rtp_allow_receiving(call->av_call->audio_rtp);
 | 
			
		||||
        rtp_allow_receiving_mark(call->av_call->audio_rtp);
 | 
			
		||||
    } else {
 | 
			
		||||
        rtp_stop_receiving(call->av_call->audio_rtp);
 | 
			
		||||
        rtp_stop_receiving_mark(call->av_call->audio_rtp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((call->peer_capabilities & MSI_CAP_S_VIDEO) != 0) {
 | 
			
		||||
        rtp_allow_receiving(call->av_call->video_rtp);
 | 
			
		||||
        rtp_allow_receiving_mark(call->av_call->video_rtp);
 | 
			
		||||
    } else {
 | 
			
		||||
        rtp_stop_receiving(call->av_call->video_rtp);
 | 
			
		||||
        rtp_stop_receiving_mark(call->av_call->video_rtp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities);
 | 
			
		||||
@@ -1204,6 +1292,7 @@ static int callback_capabilites(void *object, MSICall *call)
 | 
			
		||||
    pthread_mutex_unlock(toxav->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool audio_bit_rate_invalid(uint32_t bit_rate)
 | 
			
		||||
{
 | 
			
		||||
    /* Opus RFC 6716 section-2.1.1 dictates the following:
 | 
			
		||||
@@ -1211,6 +1300,7 @@ static bool audio_bit_rate_invalid(uint32_t bit_rate)
 | 
			
		||||
     */
 | 
			
		||||
    return bit_rate < 6 || bit_rate > 510;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool video_bit_rate_invalid(uint32_t bit_rate)
 | 
			
		||||
{
 | 
			
		||||
    /* https://www.webmproject.org/docs/webm-sdk/structvpx__codec__enc__cfg.html shows the following:
 | 
			
		||||
@@ -1222,6 +1312,7 @@ static bool video_bit_rate_invalid(uint32_t bit_rate)
 | 
			
		||||
     */
 | 
			
		||||
    return bit_rate > UINT32_MAX;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state)
 | 
			
		||||
{
 | 
			
		||||
    if (av->scb != nullptr) {
 | 
			
		||||
@@ -1239,12 +1330,17 @@ static ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, Toxav_Err_Call *er
 | 
			
		||||
    Toxav_Err_Call rc = TOXAV_ERR_CALL_OK;
 | 
			
		||||
    ToxAVCall *call = nullptr;
 | 
			
		||||
 | 
			
		||||
    if (!m_friend_exists(av->m, friend_number)) {
 | 
			
		||||
    Tox_Err_Friend_Query f_con_query_error;
 | 
			
		||||
    Tox_Connection f_con_status = TOX_CONNECTION_NONE;
 | 
			
		||||
 | 
			
		||||
    if (!tox_friend_exists(av->tox, friend_number)) {
 | 
			
		||||
        rc = TOXAV_ERR_CALL_FRIEND_NOT_FOUND;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m_get_friend_connectionstatus(av->m, friend_number) < 1) {
 | 
			
		||||
    f_con_status = tox_friend_get_connection_status(av->tox, friend_number, &f_con_query_error);
 | 
			
		||||
 | 
			
		||||
    if (f_con_status == TOX_CONNECTION_NONE) {
 | 
			
		||||
        rc = TOXAV_ERR_CALL_FRIEND_NOT_CONNECTED;
 | 
			
		||||
        goto RETURN;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1323,16 +1419,6 @@ RETURN:
 | 
			
		||||
    return call;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ToxAVCall *call_get(ToxAV *av, uint32_t friend_number)
 | 
			
		||||
{
 | 
			
		||||
    /* Assumes mutex locked */
 | 
			
		||||
    if (av->calls == nullptr || av->calls_tail < friend_number) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return av->calls[friend_number];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static ToxAVCall *call_remove(ToxAVCall *call)
 | 
			
		||||
{
 | 
			
		||||
    if (call == nullptr) {
 | 
			
		||||
@@ -1399,7 +1485,7 @@ static bool call_prepare_transmission(ToxAVCall *call)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (call->active) {
 | 
			
		||||
        LOGGER_WARNING(av->m->log, "Call already active!");
 | 
			
		||||
        LOGGER_WARNING(av->log, "Call already active!");
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -1412,43 +1498,37 @@ static bool call_prepare_transmission(ToxAVCall *call)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Prepare bwc */
 | 
			
		||||
    call->bwc = bwc_new(av->m, av->tox, call->friend_number, callback_bwc, call, av->toxav_mono_time);
 | 
			
		||||
    call->bwc = bwc_new(av->log, av->tox, call->friend_number, callback_bwc, call, av->toxav_mono_time);
 | 
			
		||||
 | 
			
		||||
    if (call->bwc == nullptr) {
 | 
			
		||||
        LOGGER_ERROR(av->m->log, "Failed to create new bwc");
 | 
			
		||||
        goto FAILURE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {   /* Prepare audio */
 | 
			
		||||
        call->audio = ac_new(av->toxav_mono_time, av->m->log, av, call->friend_number, av->acb, av->acb_user_data);
 | 
			
		||||
    { /* Prepare audio */
 | 
			
		||||
        call->audio = ac_new(av->toxav_mono_time, av->log, av, call->friend_number, av->acb, av->acb_user_data);
 | 
			
		||||
 | 
			
		||||
        if (call->audio == nullptr) {
 | 
			
		||||
            LOGGER_ERROR(av->m->log, "Failed to create audio codec session");
 | 
			
		||||
            LOGGER_ERROR(av->log, "Failed to create audio codec session");
 | 
			
		||||
            goto FAILURE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        call->audio_rtp = rtp_new(RTP_TYPE_AUDIO, av->m, av->tox, call->friend_number, call->bwc,
 | 
			
		||||
        call->audio_rtp = rtp_new(av->log, RTP_TYPE_AUDIO, av->tox, av, call->friend_number, call->bwc,
 | 
			
		||||
                                  call->audio, ac_queue_message);
 | 
			
		||||
 | 
			
		||||
        if (call->audio_rtp == nullptr) {
 | 
			
		||||
            LOGGER_ERROR(av->m->log, "Failed to create audio rtp session");
 | 
			
		||||
            LOGGER_ERROR(av->log, "Failed to create audio rtp session");
 | 
			
		||||
            goto FAILURE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {   /* Prepare video */
 | 
			
		||||
        call->video = vc_new(av->toxav_mono_time, av->m->log, av, call->friend_number, av->vcb, av->vcb_user_data);
 | 
			
		||||
    { /* Prepare video */
 | 
			
		||||
        call->video = vc_new(av->log, av->toxav_mono_time, av, call->friend_number, av->vcb, av->vcb_user_data);
 | 
			
		||||
 | 
			
		||||
        if (call->video == nullptr) {
 | 
			
		||||
            LOGGER_ERROR(av->m->log, "Failed to create video codec session");
 | 
			
		||||
            LOGGER_ERROR(av->log, "Failed to create video codec session");
 | 
			
		||||
            goto FAILURE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        call->video_rtp = rtp_new(RTP_TYPE_VIDEO, av->m, av->tox, call->friend_number, call->bwc,
 | 
			
		||||
        call->video_rtp = rtp_new(av->log, RTP_TYPE_VIDEO, av->tox, av, call->friend_number, call->bwc,
 | 
			
		||||
                                  call->video, vc_queue_message);
 | 
			
		||||
 | 
			
		||||
        if (call->video_rtp == nullptr) {
 | 
			
		||||
            LOGGER_ERROR(av->m->log, "Failed to create video rtp session");
 | 
			
		||||
            LOGGER_ERROR(av->log, "Failed to create video rtp session");
 | 
			
		||||
            goto FAILURE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1458,11 +1538,11 @@ static bool call_prepare_transmission(ToxAVCall *call)
 | 
			
		||||
 | 
			
		||||
FAILURE:
 | 
			
		||||
    bwc_kill(call->bwc);
 | 
			
		||||
    rtp_kill(call->audio_rtp);
 | 
			
		||||
    rtp_kill(av->log, call->audio_rtp);
 | 
			
		||||
    ac_kill(call->audio);
 | 
			
		||||
    call->audio_rtp = nullptr;
 | 
			
		||||
    call->audio = nullptr;
 | 
			
		||||
    rtp_kill(call->video_rtp);
 | 
			
		||||
    rtp_kill(av->log, call->video_rtp);
 | 
			
		||||
    vc_kill(call->video);
 | 
			
		||||
    call->video_rtp = nullptr;
 | 
			
		||||
    call->video = nullptr;
 | 
			
		||||
@@ -1489,12 +1569,14 @@ static void call_kill_transmission(ToxAVCall *call)
 | 
			
		||||
 | 
			
		||||
    bwc_kill(call->bwc);
 | 
			
		||||
 | 
			
		||||
    rtp_kill(call->audio_rtp);
 | 
			
		||||
    const ToxAV *av = call->av;
 | 
			
		||||
 | 
			
		||||
    rtp_kill(av->log, call->audio_rtp);
 | 
			
		||||
    ac_kill(call->audio);
 | 
			
		||||
    call->audio_rtp = nullptr;
 | 
			
		||||
    call->audio = nullptr;
 | 
			
		||||
 | 
			
		||||
    rtp_kill(call->video_rtp);
 | 
			
		||||
    rtp_kill(av->log, call->video_rtp);
 | 
			
		||||
    vc_kill(call->video);
 | 
			
		||||
    call->video_rtp = nullptr;
 | 
			
		||||
    call->video = nullptr;
 | 
			
		||||
@@ -1502,3 +1584,12 @@ static void call_kill_transmission(ToxAVCall *call)
 | 
			
		||||
    pthread_mutex_destroy(call->mutex_audio);
 | 
			
		||||
    pthread_mutex_destroy(call->mutex_video);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Mono_Time *toxav_get_av_mono_time(const ToxAV *av)
 | 
			
		||||
{
 | 
			
		||||
    if (av == nullptr) {
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return av->toxav_mono_time;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										34
									
								
								external/toxcore/c-toxcore/toxav/toxav.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								external/toxcore/c-toxcore/toxav/toxav.h
									
									
									
									
										vendored
									
									
								
							@@ -73,6 +73,8 @@ typedef struct Tox Tox;
 | 
			
		||||
#endif /* !TOX_DEFINED */
 | 
			
		||||
#endif /* !APIGEN_IGNORE */
 | 
			
		||||
 | 
			
		||||
#ifndef TOXAV_DEFINED
 | 
			
		||||
#define TOXAV_DEFINED
 | 
			
		||||
/**
 | 
			
		||||
 * @brief The ToxAV instance type.
 | 
			
		||||
 *
 | 
			
		||||
@@ -83,6 +85,7 @@ typedef struct Tox Tox;
 | 
			
		||||
 * notifying peers.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct ToxAV ToxAV;
 | 
			
		||||
#endif /* TOXAV_DEFINED */
 | 
			
		||||
 | 
			
		||||
/** @{
 | 
			
		||||
 * @brief Creation and destruction
 | 
			
		||||
@@ -246,9 +249,9 @@ typedef enum Toxav_Err_Call {
 | 
			
		||||
 * receiving are both enabled by default.
 | 
			
		||||
 *
 | 
			
		||||
 * @param friend_number The friend number of the friend that should be called.
 | 
			
		||||
 * @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable
 | 
			
		||||
 * @param audio_bit_rate Audio bit rate in kbit/sec. Set this to 0 to disable
 | 
			
		||||
 *   audio sending.
 | 
			
		||||
 * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable
 | 
			
		||||
 * @param video_bit_rate Video bit rate in kbit/sec. Set this to 0 to disable
 | 
			
		||||
 *   video sending.
 | 
			
		||||
 */
 | 
			
		||||
bool toxav_call(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
 | 
			
		||||
@@ -315,9 +318,9 @@ typedef enum Toxav_Err_Answer {
 | 
			
		||||
 * enabled by default.
 | 
			
		||||
 *
 | 
			
		||||
 * @param friend_number The friend number of the friend that is calling.
 | 
			
		||||
 * @param audio_bit_rate Audio bit rate in Kb/sec. Set this to 0 to disable
 | 
			
		||||
 * @param audio_bit_rate Audio bit rate in kbit/sec. Set this to 0 to disable
 | 
			
		||||
 *   audio sending.
 | 
			
		||||
 * @param video_bit_rate Video bit rate in Kb/sec. Set this to 0 to disable
 | 
			
		||||
 * @param video_bit_rate Video bit rate in kbit/sec. Set this to 0 to disable
 | 
			
		||||
 *   video sending.
 | 
			
		||||
 */
 | 
			
		||||
bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
 | 
			
		||||
@@ -597,11 +600,11 @@ bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t pcm
 | 
			
		||||
                            uint8_t channels, uint32_t sampling_rate, Toxav_Err_Send_Frame *error);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set the bit rate to be used in subsequent video frames.
 | 
			
		||||
 * Set the bit rate to be used in subsequent audio frames.
 | 
			
		||||
 *
 | 
			
		||||
 * @param friend_number The friend number of the friend for which to set the
 | 
			
		||||
 *   bit rate.
 | 
			
		||||
 * @param bit_rate The new audio bit rate in Kb/sec. Set to 0 to disable.
 | 
			
		||||
 * @param bit_rate The new audio bit rate in kbit/sec. Set to 0 to disable.
 | 
			
		||||
 *
 | 
			
		||||
 * @return true on success.
 | 
			
		||||
 */
 | 
			
		||||
@@ -614,7 +617,7 @@ bool toxav_audio_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
 | 
			
		||||
 *
 | 
			
		||||
 * @param friend_number The friend number of the friend for which to set the
 | 
			
		||||
 *   bit rate.
 | 
			
		||||
 * @param audio_bit_rate Suggested maximum audio bit rate in Kb/sec.
 | 
			
		||||
 * @param audio_bit_rate Suggested maximum audio bit rate in kbit/sec.
 | 
			
		||||
 */
 | 
			
		||||
typedef void toxav_audio_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, void *user_data);
 | 
			
		||||
 | 
			
		||||
@@ -627,9 +630,10 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback,
 | 
			
		||||
/**
 | 
			
		||||
 * Send a video frame to a friend.
 | 
			
		||||
 *
 | 
			
		||||
 * Y - plane should be of size: `height * width`
 | 
			
		||||
 * U - plane should be of size: `(height/2) * (width/2)`
 | 
			
		||||
 * V - plane should be of size: `(height/2) * (width/2)`
 | 
			
		||||
 * The video frame needs to be planar YUV420.
 | 
			
		||||
 * Y - plane should be of size: `width * height`
 | 
			
		||||
 * U - plane should be of size: `(width/2) * (height/2)`
 | 
			
		||||
 * V - plane should be of size: `(width/2) * (height/2)`
 | 
			
		||||
 *
 | 
			
		||||
 * @param friend_number The friend number of the friend to which to send a video
 | 
			
		||||
 *   frame.
 | 
			
		||||
@@ -641,9 +645,9 @@ void toxav_callback_audio_bit_rate(ToxAV *av, toxav_audio_bit_rate_cb *callback,
 | 
			
		||||
 */
 | 
			
		||||
bool toxav_video_send_frame(
 | 
			
		||||
    ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height,
 | 
			
		||||
    const uint8_t y[/*! height * width */],
 | 
			
		||||
    const uint8_t u[/*! height/2 * width/2 */],
 | 
			
		||||
    const uint8_t v[/*! height/2 * width/2 */],
 | 
			
		||||
    const uint8_t y[/*! width * height */],
 | 
			
		||||
    const uint8_t u[/*! width/2 * height/2 */],
 | 
			
		||||
    const uint8_t v[/*! width/2 * height/2 */],
 | 
			
		||||
    Toxav_Err_Send_Frame *error);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -651,7 +655,7 @@ bool toxav_video_send_frame(
 | 
			
		||||
 *
 | 
			
		||||
 * @param friend_number The friend number of the friend for which to set the
 | 
			
		||||
 *   bit rate.
 | 
			
		||||
 * @param bit_rate The new video bit rate in Kb/sec. Set to 0 to disable.
 | 
			
		||||
 * @param bit_rate The new video bit rate in kbit/sec. Set to 0 to disable.
 | 
			
		||||
 *
 | 
			
		||||
 * @return true on success.
 | 
			
		||||
 */
 | 
			
		||||
@@ -664,7 +668,7 @@ bool toxav_video_set_bit_rate(ToxAV *av, uint32_t friend_number, uint32_t bit_ra
 | 
			
		||||
 *
 | 
			
		||||
 * @param friend_number The friend number of the friend for which to set the
 | 
			
		||||
 *   bit rate.
 | 
			
		||||
 * @param video_bit_rate Suggested maximum video bit rate in Kb/sec.
 | 
			
		||||
 * @param video_bit_rate Suggested maximum video bit rate in kbit/sec.
 | 
			
		||||
 */
 | 
			
		||||
typedef void toxav_video_bit_rate_cb(ToxAV *av, uint32_t friend_number, uint32_t video_bit_rate, void *user_data);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								external/toxcore/c-toxcore/toxav/toxav_hacks.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								external/toxcore/c-toxcore/toxav/toxav_hacks.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 * Copyright © 2016-2018 The TokTok team.
 | 
			
		||||
 * Copyright © 2013-2015 Tox project.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef C_TOXCORE_TOXAV_HACKS_H
 | 
			
		||||
#define C_TOXCORE_TOXAV_HACKS_H
 | 
			
		||||
 | 
			
		||||
#include "bwcontroller.h"
 | 
			
		||||
#include "msi.h"
 | 
			
		||||
#include "rtp.h"
 | 
			
		||||
 | 
			
		||||
#ifndef TOXAV_CALL_DEFINED
 | 
			
		||||
#define TOXAV_CALL_DEFINED
 | 
			
		||||
typedef struct ToxAVCall ToxAVCall;
 | 
			
		||||
#endif /* TOXAV_CALL_DEFINED */
 | 
			
		||||
 | 
			
		||||
non_null()
 | 
			
		||||
ToxAVCall *call_get(ToxAV *av, uint32_t friend_number);
 | 
			
		||||
 | 
			
		||||
non_null()
 | 
			
		||||
RTPSession *rtp_session_get(ToxAVCall *call, int payload_type);
 | 
			
		||||
 | 
			
		||||
non_null()
 | 
			
		||||
MSISession *tox_av_msi_get(const ToxAV *av);
 | 
			
		||||
 | 
			
		||||
non_null()
 | 
			
		||||
BWController *bwc_controller_get(const ToxAVCall *call);
 | 
			
		||||
 | 
			
		||||
non_null()
 | 
			
		||||
Mono_Time *toxav_get_av_mono_time(const ToxAV *av);
 | 
			
		||||
 | 
			
		||||
non_null()
 | 
			
		||||
const Logger *toxav_get_logger(const ToxAV *av);
 | 
			
		||||
 | 
			
		||||
#endif /* C_TOXCORE_TOXAV_HACKS_H */
 | 
			
		||||
							
								
								
									
										7
									
								
								external/toxcore/c-toxcore/toxav/video.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								external/toxcore/c-toxcore/toxav/video.c
									
									
									
									
										vendored
									
									
								
							@@ -143,7 +143,7 @@ static void vc_init_encoder_cfg(const Logger *log, vpx_codec_enc_cfg_t *cfg, int
 | 
			
		||||
#endif /* 0 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number,
 | 
			
		||||
VCSession *vc_new(const Logger *log, Mono_Time *mono_time, ToxAV *av, uint32_t friend_number,
 | 
			
		||||
                  toxav_video_receive_frame_cb *cb, void *cb_data)
 | 
			
		||||
{
 | 
			
		||||
    VCSession *vc = (VCSession *)calloc(1, sizeof(VCSession));
 | 
			
		||||
@@ -216,7 +216,7 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f
 | 
			
		||||
 | 
			
		||||
    /* Set encoder to some initial values
 | 
			
		||||
     */
 | 
			
		||||
    vpx_codec_enc_cfg_t  cfg;
 | 
			
		||||
    vpx_codec_enc_cfg_t cfg;
 | 
			
		||||
    vc_init_encoder_cfg(log, &cfg, 1);
 | 
			
		||||
 | 
			
		||||
    LOGGER_DEBUG(log, "Using VP8 codec for encoder (0.1)");
 | 
			
		||||
@@ -250,6 +250,7 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#endif /* 0 */
 | 
			
		||||
 | 
			
		||||
    vc->linfts = current_time_monotonic(mono_time);
 | 
			
		||||
    vc->lcfd = 60;
 | 
			
		||||
    vc->vcb = cb;
 | 
			
		||||
@@ -258,12 +259,14 @@ VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t f
 | 
			
		||||
    vc->av = av;
 | 
			
		||||
    vc->log = log;
 | 
			
		||||
    return vc;
 | 
			
		||||
 | 
			
		||||
BASE_CLEANUP_1:
 | 
			
		||||
    vpx_codec_destroy(vc->decoder);
 | 
			
		||||
BASE_CLEANUP:
 | 
			
		||||
    pthread_mutex_destroy(vc->queue_mutex);
 | 
			
		||||
    rb_kill(vc->vbuf_raw);
 | 
			
		||||
    free(vc);
 | 
			
		||||
 | 
			
		||||
    return nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								external/toxcore/c-toxcore/toxav/video.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								external/toxcore/c-toxcore/toxav/video.h
									
									
									
									
										vendored
									
									
								
							@@ -33,7 +33,6 @@ typedef struct VCSession {
 | 
			
		||||
    uint64_t linfts; /* Last received frame time stamp */
 | 
			
		||||
    uint32_t lcfd; /* Last calculated frame duration for incoming video payload */
 | 
			
		||||
 | 
			
		||||
    const Logger *log;
 | 
			
		||||
    ToxAV *av;
 | 
			
		||||
    uint32_t friend_number;
 | 
			
		||||
 | 
			
		||||
@@ -42,9 +41,10 @@ typedef struct VCSession {
 | 
			
		||||
    void *vcb_user_data;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_t queue_mutex[1];
 | 
			
		||||
    const Logger *log;
 | 
			
		||||
} VCSession;
 | 
			
		||||
 | 
			
		||||
VCSession *vc_new(Mono_Time *mono_time, const Logger *log, ToxAV *av, uint32_t friend_number,
 | 
			
		||||
VCSession *vc_new(const Logger *log, Mono_Time *mono_time, ToxAV *av, uint32_t friend_number,
 | 
			
		||||
                  toxav_video_receive_frame_cb *cb, void *cb_data);
 | 
			
		||||
void vc_kill(VCSession *vc);
 | 
			
		||||
void vc_iterate(VCSession *vc);
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ exports_files(
 | 
			
		||||
        "tox.h",
 | 
			
		||||
        "tox_private.h",
 | 
			
		||||
    ],
 | 
			
		||||
    visibility = ["//c-toxcore:__pkg__"],
 | 
			
		||||
    visibility = ["//c-toxcore:__subpackages__"],
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cc_library(
 | 
			
		||||
@@ -661,7 +661,10 @@ cc_library(
 | 
			
		||||
    name = "net_crypto",
 | 
			
		||||
    srcs = ["net_crypto.c"],
 | 
			
		||||
    hdrs = ["net_crypto.h"],
 | 
			
		||||
    visibility = ["//c-toxcore/auto_tests:__pkg__"],
 | 
			
		||||
    visibility = [
 | 
			
		||||
        "//c-toxcore/auto_tests:__pkg__",
 | 
			
		||||
        "//c-toxcore/toxav:__pkg__",
 | 
			
		||||
    ],
 | 
			
		||||
    deps = [
 | 
			
		||||
        ":DHT",
 | 
			
		||||
        ":LAN_discovery",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								external/toxcore/c-toxcore/toxcore/DHT.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								external/toxcore/c-toxcore/toxcore/DHT.c
									
									
									
									
										vendored
									
									
								
							@@ -380,12 +380,12 @@ int dht_create_packet(const Memory *mem, const Random *rng,
 | 
			
		||||
 | 
			
		||||
    const int encrypted_length = encrypt_data_symmetric(shared_key, nonce, plain, plain_length, encrypted);
 | 
			
		||||
 | 
			
		||||
    if (encrypted_length == -1) {
 | 
			
		||||
    if (encrypted_length < 0) {
 | 
			
		||||
        mem_delete(mem, encrypted);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + encrypted_length) {
 | 
			
		||||
    if (length < 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + (size_t)encrypted_length) {
 | 
			
		||||
        mem_delete(mem, encrypted);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1347,15 +1347,15 @@ static int sendnodes_ipv6(const DHT *dht, const IP_Port *ip_port, const uint8_t
 | 
			
		||||
    plain[0] = num_nodes;
 | 
			
		||||
    memcpy(plain + 1 + nodes_length, sendback_data, length);
 | 
			
		||||
 | 
			
		||||
    const uint32_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE;
 | 
			
		||||
    const uint32_t data_size = 1 + nodes_length + length + crypto_size;
 | 
			
		||||
    const uint16_t crypto_size = 1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE;
 | 
			
		||||
    const uint16_t data_size = 1 + nodes_length + length + crypto_size;
 | 
			
		||||
    VLA(uint8_t, data, data_size);
 | 
			
		||||
 | 
			
		||||
    const int len = dht_create_packet(dht->mem, dht->rng,
 | 
			
		||||
                                      dht->self_public_key, shared_encryption_key, NET_PACKET_SEND_NODES_IPV6,
 | 
			
		||||
                                      plain, 1 + nodes_length + length, data, data_size);
 | 
			
		||||
 | 
			
		||||
    if (len != data_size) {
 | 
			
		||||
    if (len < 0 || (uint32_t)len != data_size) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										98
									
								
								external/toxcore/c-toxcore/toxcore/Messenger.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										98
									
								
								external/toxcore/c-toxcore/toxcore/Messenger.c
									
									
									
									
										vendored
									
									
								
							@@ -472,10 +472,6 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m->friend_connectionstatuschange_internal != nullptr) {
 | 
			
		||||
        m->friend_connectionstatuschange_internal(m, friendnumber, false, m->friend_connectionstatuschange_internal_userdata);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    clear_receipts(m, friendnumber);
 | 
			
		||||
    remove_request_received(m->fr, m->friendlist[friendnumber].real_pk);
 | 
			
		||||
    friend_connection_callbacks(m->fr_c, m->friendlist[friendnumber].friendcon_id, MESSENGER_CALLBACK_INDEX, nullptr,
 | 
			
		||||
@@ -1027,13 +1023,6 @@ void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *funct
 | 
			
		||||
    m->core_connection_change = function;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void m_callback_connectionstatus_internal_av(Messenger *m, m_friend_connectionstatuschange_internal_cb *function,
 | 
			
		||||
        void *userdata)
 | 
			
		||||
{
 | 
			
		||||
    m->friend_connectionstatuschange_internal = function;
 | 
			
		||||
    m->friend_connectionstatuschange_internal_userdata = userdata;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
non_null(1) nullable(3)
 | 
			
		||||
static void check_friend_tcp_udp(Messenger *m, int32_t friendnumber, void *userdata)
 | 
			
		||||
{
 | 
			
		||||
@@ -1081,11 +1070,6 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui
 | 
			
		||||
        m->friendlist[friendnumber].status = status;
 | 
			
		||||
 | 
			
		||||
        check_friend_tcp_udp(m, friendnumber, userdata);
 | 
			
		||||
 | 
			
		||||
        if (m->friend_connectionstatuschange_internal != nullptr) {
 | 
			
		||||
            m->friend_connectionstatuschange_internal(m, friendnumber, is_online,
 | 
			
		||||
                    m->friend_connectionstatuschange_internal_userdata);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1855,23 +1839,6 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, bool outbound,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief Set the callback for msi packets. */
 | 
			
		||||
void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata)
 | 
			
		||||
{
 | 
			
		||||
    m->msi_packet = function;
 | 
			
		||||
    m->msi_packet_userdata = userdata;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief Send an msi packet.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval true on success
 | 
			
		||||
 * @retval false on failure
 | 
			
		||||
 */
 | 
			
		||||
bool m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length)
 | 
			
		||||
{
 | 
			
		||||
    return write_cryptpacket_id(m, friendnumber, PACKET_ID_MSI, data, length, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *data, uint16_t length,
 | 
			
		||||
                                 void *userdata)
 | 
			
		||||
{
 | 
			
		||||
@@ -1881,17 +1848,6 @@ static int m_handle_lossy_packet(void *object, int friendcon_id, const uint8_t *
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (data[0] <= PACKET_ID_RANGE_LOSSY_AV_END) {
 | 
			
		||||
        const RTP_Packet_Handler *const ph =
 | 
			
		||||
            &m->friendlist[friendcon_id].lossy_rtp_packethandlers[data[0] % PACKET_ID_RANGE_LOSSY_AV_SIZE];
 | 
			
		||||
 | 
			
		||||
        if (ph->function != nullptr) {
 | 
			
		||||
            return ph->function(m, friendcon_id, data, length, ph->object);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m->lossy_packethandler != nullptr) {
 | 
			
		||||
        m->lossy_packethandler(m, friendcon_id, data[0], data, length, userdata);
 | 
			
		||||
    }
 | 
			
		||||
@@ -1904,38 +1860,6 @@ void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb
 | 
			
		||||
    m->lossy_packethandler = lossy_packethandler;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, m_lossy_rtp_packet_cb *function,
 | 
			
		||||
                          void *object)
 | 
			
		||||
{
 | 
			
		||||
    if (!m_friend_exists(m, friendnumber)) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (byte < PACKET_ID_RANGE_LOSSY_AV_START || byte > PACKET_ID_RANGE_LOSSY_AV_END) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m->friendlist[friendnumber].lossy_rtp_packethandlers[byte % PACKET_ID_RANGE_LOSSY_AV_SIZE].function = function;
 | 
			
		||||
    m->friendlist[friendnumber].lossy_rtp_packethandlers[byte % PACKET_ID_RANGE_LOSSY_AV_SIZE].object = object;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief High level function to send custom lossy packets.
 | 
			
		||||
 *
 | 
			
		||||
 * TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets.
 | 
			
		||||
 * Meanwhile, m_handle_lossy_packet routes custom packets to custom_lossy_packet_registerhandler
 | 
			
		||||
 * as you would expect from its name.
 | 
			
		||||
 *
 | 
			
		||||
 * I.e. custom_lossy_packet_registerhandler's "custom lossy packet" and this "custom lossy packet"
 | 
			
		||||
 * are not the same set of packets.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval -1 if friend invalid.
 | 
			
		||||
 * @retval -2 if length wrong.
 | 
			
		||||
 * @retval -3 if first byte invalid.
 | 
			
		||||
 * @retval -4 if friend offline.
 | 
			
		||||
 * @retval -5 if packet failed to send because of other error.
 | 
			
		||||
 * @retval 0 on success.
 | 
			
		||||
 */
 | 
			
		||||
int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
    if (!m_friend_exists(m, friendnumber)) {
 | 
			
		||||
@@ -1946,7 +1870,6 @@ int m_send_custom_lossy_packet(const Messenger *m, int32_t friendnumber, const u
 | 
			
		||||
        return -2;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO(oxij): send_lossy_cryptpacket makes this check already, similarly for other similar places
 | 
			
		||||
    if (data[0] < PACKET_ID_RANGE_LOSSY_START || data[0] > PACKET_ID_RANGE_LOSSY_END) {
 | 
			
		||||
        return -3;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1974,7 +1897,10 @@ static int handle_custom_lossless_packet(void *object, int friend_num, const uin
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (packet[0] < PACKET_ID_RANGE_LOSSLESS_CUSTOM_START || packet[0] > PACKET_ID_RANGE_LOSSLESS_CUSTOM_END) {
 | 
			
		||||
        return -1;
 | 
			
		||||
        // allow PACKET_ID_MSI packets to be handled by custom packet handler
 | 
			
		||||
        if (packet[0] != PACKET_ID_MSI) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m->lossless_packethandler != nullptr) {
 | 
			
		||||
@@ -2356,20 +2282,6 @@ static int m_handle_packet_file_data(Messenger *m, const int friendcon_id, const
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
non_null(1, 3) nullable(5)
 | 
			
		||||
static int m_handle_packet_msi(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata)
 | 
			
		||||
{
 | 
			
		||||
    if (data_length == 0) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (m->msi_packet != nullptr) {
 | 
			
		||||
        m->msi_packet(m, friendcon_id, data, data_length, m->msi_packet_userdata);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
non_null(1, 3) nullable(5)
 | 
			
		||||
static int m_handle_packet_invite_groupchat(Messenger *m, const int friendcon_id, const uint8_t *data, const uint16_t data_length, void *userdata)
 | 
			
		||||
{
 | 
			
		||||
@@ -2443,7 +2355,7 @@ static int m_handle_packet(void *object, int friendcon_id, const uint8_t *data,
 | 
			
		||||
        case PACKET_ID_FILE_DATA:
 | 
			
		||||
            return m_handle_packet_file_data(m, friendcon_id, payload, payload_length, userdata);
 | 
			
		||||
        case PACKET_ID_MSI:
 | 
			
		||||
            return m_handle_packet_msi(m, friendcon_id, payload, payload_length, userdata);
 | 
			
		||||
            return handle_custom_lossless_packet(object, friendcon_id, data, length, userdata);
 | 
			
		||||
        case PACKET_ID_INVITE_GROUPCHAT:
 | 
			
		||||
            return m_handle_packet_invite_groupchat(m, friendcon_id, payload, payload_length, userdata);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										51
									
								
								external/toxcore/c-toxcore/toxcore/Messenger.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								external/toxcore/c-toxcore/toxcore/Messenger.h
									
									
									
									
										vendored
									
									
								
							@@ -200,20 +200,10 @@ typedef void m_friend_lossy_packet_cb(Messenger *m, uint32_t friend_number, uint
 | 
			
		||||
                                      size_t length, void *user_data);
 | 
			
		||||
typedef void m_friend_lossless_packet_cb(Messenger *m, uint32_t friend_number, uint8_t packet_id, const uint8_t *data,
 | 
			
		||||
        size_t length, void *user_data);
 | 
			
		||||
typedef void m_friend_connectionstatuschange_internal_cb(Messenger *m, uint32_t friend_number,
 | 
			
		||||
        bool is_online, void *user_data);
 | 
			
		||||
typedef void m_conference_invite_cb(Messenger *m, uint32_t friend_number, const uint8_t *cookie, uint16_t length,
 | 
			
		||||
                                    void *user_data);
 | 
			
		||||
typedef void m_group_invite_cb(const Messenger *m, uint32_t friend_number, const uint8_t *invite_data, size_t length,
 | 
			
		||||
                               const uint8_t *group_name, size_t group_name_length, void *user_data);
 | 
			
		||||
typedef void m_msi_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length,
 | 
			
		||||
                             void *user_data);
 | 
			
		||||
typedef int m_lossy_rtp_packet_cb(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object);
 | 
			
		||||
 | 
			
		||||
typedef struct RTP_Packet_Handler {
 | 
			
		||||
    m_lossy_rtp_packet_cb *function;
 | 
			
		||||
    void *object;
 | 
			
		||||
} RTP_Packet_Handler;
 | 
			
		||||
 | 
			
		||||
typedef struct Friend {
 | 
			
		||||
    uint8_t real_pk[CRYPTO_PUBLIC_KEY_SIZE];
 | 
			
		||||
@@ -243,8 +233,6 @@ typedef struct Friend {
 | 
			
		||||
    uint32_t num_sending_files;
 | 
			
		||||
    struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES];
 | 
			
		||||
 | 
			
		||||
    RTP_Packet_Handler lossy_rtp_packethandlers[PACKET_ID_RANGE_LOSSY_AV_SIZE];
 | 
			
		||||
 | 
			
		||||
    struct Receipts *receipts_start;
 | 
			
		||||
    struct Receipts *receipts_end;
 | 
			
		||||
} Friend;
 | 
			
		||||
@@ -301,8 +289,6 @@ struct Messenger {
 | 
			
		||||
    m_friend_typing_cb *friend_typingchange;
 | 
			
		||||
    m_friend_read_receipt_cb *read_receipt;
 | 
			
		||||
    m_friend_connection_status_cb *friend_connectionstatuschange;
 | 
			
		||||
    m_friend_connectionstatuschange_internal_cb *friend_connectionstatuschange_internal;
 | 
			
		||||
    void *friend_connectionstatuschange_internal_userdata;
 | 
			
		||||
 | 
			
		||||
    struct Group_Chats *conferences_object;
 | 
			
		||||
    m_conference_invite_cb *conference_invite;
 | 
			
		||||
@@ -314,9 +300,6 @@ struct Messenger {
 | 
			
		||||
    m_file_recv_chunk_cb *file_filedata;
 | 
			
		||||
    m_file_chunk_request_cb *file_reqchunk;
 | 
			
		||||
 | 
			
		||||
    m_msi_packet_cb *msi_packet;
 | 
			
		||||
    void *msi_packet_userdata;
 | 
			
		||||
 | 
			
		||||
    m_friend_lossy_packet_cb *lossy_packethandler;
 | 
			
		||||
    m_friend_lossless_packet_cb *lossless_packethandler;
 | 
			
		||||
 | 
			
		||||
@@ -614,10 +597,6 @@ non_null() void m_callback_read_receipt(Messenger *m, m_friend_read_receipt_cb *
 | 
			
		||||
 */
 | 
			
		||||
non_null() void m_callback_connectionstatus(Messenger *m, m_friend_connection_status_cb *function);
 | 
			
		||||
 | 
			
		||||
/** Same as previous but for internal A/V core usage only */
 | 
			
		||||
non_null() void m_callback_connectionstatus_internal_av(
 | 
			
		||||
    Messenger *m, m_friend_connectionstatuschange_internal_cb *function, void *userdata);
 | 
			
		||||
 | 
			
		||||
/** @brief Set the callback for typing changes. */
 | 
			
		||||
non_null() void m_callback_core_connection(Messenger *m, m_self_connection_status_cb *function);
 | 
			
		||||
 | 
			
		||||
@@ -731,42 +710,12 @@ non_null(1) nullable(5)
 | 
			
		||||
int send_file_data(const Messenger *m, int32_t friendnumber, uint32_t filenumber, uint64_t position,
 | 
			
		||||
                   const uint8_t *data, uint16_t length);
 | 
			
		||||
 | 
			
		||||
/*** A/V related */
 | 
			
		||||
 | 
			
		||||
/** @brief Set the callback for msi packets. */
 | 
			
		||||
non_null(1) nullable(2, 3)
 | 
			
		||||
void m_callback_msi_packet(Messenger *m, m_msi_packet_cb *function, void *userdata);
 | 
			
		||||
 | 
			
		||||
/** @brief Send an msi packet.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval true on success
 | 
			
		||||
 * @retval false on failure
 | 
			
		||||
 */
 | 
			
		||||
non_null()
 | 
			
		||||
bool m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data, uint16_t length);
 | 
			
		||||
 | 
			
		||||
/** @brief Set handlers for lossy rtp packets.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval -1 on failure.
 | 
			
		||||
 * @retval 0 on success.
 | 
			
		||||
 */
 | 
			
		||||
non_null(1) nullable(4, 5)
 | 
			
		||||
int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte,
 | 
			
		||||
                          m_lossy_rtp_packet_cb *function, void *object);
 | 
			
		||||
 | 
			
		||||
/*** CUSTOM PACKETS */
 | 
			
		||||
 | 
			
		||||
/** @brief Set handlers for custom lossy packets. */
 | 
			
		||||
non_null() void custom_lossy_packet_registerhandler(Messenger *m, m_friend_lossy_packet_cb *lossy_packethandler);
 | 
			
		||||
 | 
			
		||||
/** @brief High level function to send custom lossy packets.
 | 
			
		||||
 *
 | 
			
		||||
 * TODO(oxij): this name is confusing, because this function sends both av and custom lossy packets.
 | 
			
		||||
 * Meanwhile, m_handle_lossy_packet routes custom packets to custom_lossy_packet_registerhandler
 | 
			
		||||
 * as you would expect from its name.
 | 
			
		||||
 *
 | 
			
		||||
 * I.e. custom_lossy_packet_registerhandler's "custom lossy packet" and this "custom lossy packet"
 | 
			
		||||
 * are not the same set of packets.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval -1 if friend invalid.
 | 
			
		||||
 * @retval -2 if length wrong.
 | 
			
		||||
 
 | 
			
		||||
@@ -579,7 +579,7 @@ static int create_reply(Announcements *announce, const IP_Port *source,
 | 
			
		||||
    const int plain_reply_max_len = (int)reply_max_length -
 | 
			
		||||
                                    (1 + CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_NONCE_SIZE + CRYPTO_MAC_SIZE);
 | 
			
		||||
 | 
			
		||||
    if (plain_reply_max_len < sizeof(uint64_t)) {
 | 
			
		||||
    if (plain_reply_max_len < (int)sizeof(uint64_t)) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -109,7 +109,10 @@ static Tox_Event_Conference_Connected *tox_events_add_conference_connected(Tox_E
 | 
			
		||||
    event.type = TOX_EVENT_CONFERENCE_CONNECTED;
 | 
			
		||||
    event.data.conference_connected = conference_connected;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_conference_connected_free(conference_connected, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return conference_connected;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -177,7 +177,10 @@ static Tox_Event_Conference_Invite *tox_events_add_conference_invite(Tox_Events
 | 
			
		||||
    event.type = TOX_EVENT_CONFERENCE_INVITE;
 | 
			
		||||
    event.data.conference_invite = conference_invite;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_conference_invite_free(conference_invite, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return conference_invite;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -193,7 +193,10 @@ static Tox_Event_Conference_Message *tox_events_add_conference_message(Tox_Event
 | 
			
		||||
    event.type = TOX_EVENT_CONFERENCE_MESSAGE;
 | 
			
		||||
    event.data.conference_message = conference_message;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_conference_message_free(conference_message, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return conference_message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -109,7 +109,10 @@ static Tox_Event_Conference_Peer_List_Changed *tox_events_add_conference_peer_li
 | 
			
		||||
    event.type = TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED;
 | 
			
		||||
    event.data.conference_peer_list_changed = conference_peer_list_changed;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_conference_peer_list_changed_free(conference_peer_list_changed, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return conference_peer_list_changed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,10 @@ static Tox_Event_Conference_Peer_Name *tox_events_add_conference_peer_name(Tox_E
 | 
			
		||||
    event.type = TOX_EVENT_CONFERENCE_PEER_NAME;
 | 
			
		||||
    event.data.conference_peer_name = conference_peer_name;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_conference_peer_name_free(conference_peer_name, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return conference_peer_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,10 @@ static Tox_Event_Conference_Title *tox_events_add_conference_title(Tox_Events *e
 | 
			
		||||
    event.type = TOX_EVENT_CONFERENCE_TITLE;
 | 
			
		||||
    event.data.conference_title = conference_title;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_conference_title_free(conference_title, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return conference_title;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -162,7 +162,10 @@ static Tox_Event_File_Chunk_Request *tox_events_add_file_chunk_request(Tox_Event
 | 
			
		||||
    event.type = TOX_EVENT_FILE_CHUNK_REQUEST;
 | 
			
		||||
    event.data.file_chunk_request = file_chunk_request;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_file_chunk_request_free(file_chunk_request, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return file_chunk_request;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -207,7 +207,10 @@ static Tox_Event_File_Recv *tox_events_add_file_recv(Tox_Events *events, const M
 | 
			
		||||
    event.type = TOX_EVENT_FILE_RECV;
 | 
			
		||||
    event.data.file_recv = file_recv;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_file_recv_free(file_recv, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return file_recv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -191,7 +191,10 @@ static Tox_Event_File_Recv_Chunk *tox_events_add_file_recv_chunk(Tox_Events *eve
 | 
			
		||||
    event.type = TOX_EVENT_FILE_RECV_CHUNK;
 | 
			
		||||
    event.data.file_recv_chunk = file_recv_chunk;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_file_recv_chunk_free(file_recv_chunk, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return file_recv_chunk;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -148,7 +148,10 @@ static Tox_Event_File_Recv_Control *tox_events_add_file_recv_control(Tox_Events
 | 
			
		||||
    event.type = TOX_EVENT_FILE_RECV_CONTROL;
 | 
			
		||||
    event.data.file_recv_control = file_recv_control;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_file_recv_control_free(file_recv_control, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return file_recv_control;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,10 @@ static Tox_Event_Friend_Connection_Status *tox_events_add_friend_connection_stat
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_CONNECTION_STATUS;
 | 
			
		||||
    event.data.friend_connection_status = friend_connection_status;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_connection_status_free(friend_connection_status, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_connection_status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,10 @@ static Tox_Event_Friend_Lossless_Packet *tox_events_add_friend_lossless_packet(T
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_LOSSLESS_PACKET;
 | 
			
		||||
    event.data.friend_lossless_packet = friend_lossless_packet;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_lossless_packet_free(friend_lossless_packet, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_lossless_packet;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,10 @@ static Tox_Event_Friend_Lossy_Packet *tox_events_add_friend_lossy_packet(Tox_Eve
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_LOSSY_PACKET;
 | 
			
		||||
    event.data.friend_lossy_packet = friend_lossy_packet;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_lossy_packet_free(friend_lossy_packet, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_lossy_packet;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -177,7 +177,10 @@ static Tox_Event_Friend_Message *tox_events_add_friend_message(Tox_Events *event
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_MESSAGE;
 | 
			
		||||
    event.data.friend_message = friend_message;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_message_free(friend_message, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,10 @@ static Tox_Event_Friend_Name *tox_events_add_friend_name(Tox_Events *events, con
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_NAME;
 | 
			
		||||
    event.data.friend_name = friend_name;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_name_free(friend_name, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -130,7 +130,10 @@ static Tox_Event_Friend_Read_Receipt *tox_events_add_friend_read_receipt(Tox_Eve
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_READ_RECEIPT;
 | 
			
		||||
    event.data.friend_read_receipt = friend_read_receipt;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_read_receipt_free(friend_read_receipt, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_read_receipt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -152,7 +152,10 @@ static Tox_Event_Friend_Request *tox_events_add_friend_request(Tox_Events *event
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_REQUEST;
 | 
			
		||||
    event.data.friend_request = friend_request;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_request_free(friend_request, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_request;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,10 @@ static Tox_Event_Friend_Status *tox_events_add_friend_status(Tox_Events *events,
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_STATUS;
 | 
			
		||||
    event.data.friend_status = friend_status;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_status_free(friend_status, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,10 @@ static Tox_Event_Friend_Status_Message *tox_events_add_friend_status_message(Tox
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_STATUS_MESSAGE;
 | 
			
		||||
    event.data.friend_status_message = friend_status_message;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_status_message_free(friend_status_message, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_status_message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -130,7 +130,10 @@ static Tox_Event_Friend_Typing *tox_events_add_friend_typing(Tox_Events *events,
 | 
			
		||||
    event.type = TOX_EVENT_FRIEND_TYPING;
 | 
			
		||||
    event.data.friend_typing = friend_typing;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_friend_typing_free(friend_typing, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return friend_typing;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,10 @@ static Tox_Event_Group_Custom_Packet *tox_events_add_group_custom_packet(Tox_Eve
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_CUSTOM_PACKET;
 | 
			
		||||
    event.data.group_custom_packet = group_custom_packet;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_custom_packet_free(group_custom_packet, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_custom_packet;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,10 @@ static Tox_Event_Group_Custom_Private_Packet *tox_events_add_group_custom_privat
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET;
 | 
			
		||||
    event.data.group_custom_private_packet = group_custom_private_packet;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_custom_private_packet_free(group_custom_private_packet, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_custom_private_packet;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -203,7 +203,10 @@ static Tox_Event_Group_Invite *tox_events_add_group_invite(Tox_Events *events, c
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_INVITE;
 | 
			
		||||
    event.data.group_invite = group_invite;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_invite_free(group_invite, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_invite;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,10 @@ static Tox_Event_Group_Join_Fail *tox_events_add_group_join_fail(Tox_Events *eve
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_JOIN_FAIL;
 | 
			
		||||
    event.data.group_join_fail = group_join_fail;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_join_fail_free(group_join_fail, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_join_fail;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -209,7 +209,10 @@ static Tox_Event_Group_Message *tox_events_add_group_message(Tox_Events *events,
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_MESSAGE;
 | 
			
		||||
    event.data.group_message = group_message;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_message_free(group_message, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -164,7 +164,10 @@ static Tox_Event_Group_Moderation *tox_events_add_group_moderation(Tox_Events *e
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_MODERATION;
 | 
			
		||||
    event.data.group_moderation = group_moderation;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_moderation_free(group_moderation, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_moderation;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,10 @@ static Tox_Event_Group_Password *tox_events_add_group_password(Tox_Events *event
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_PASSWORD;
 | 
			
		||||
    event.data.group_password = group_password;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_password_free(group_password, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_password;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -237,7 +237,10 @@ static Tox_Event_Group_Peer_Exit *tox_events_add_group_peer_exit(Tox_Events *eve
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_PEER_EXIT;
 | 
			
		||||
    event.data.group_peer_exit = group_peer_exit;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_peer_exit_free(group_peer_exit, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_peer_exit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -130,7 +130,10 @@ static Tox_Event_Group_Peer_Join *tox_events_add_group_peer_join(Tox_Events *eve
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_PEER_JOIN;
 | 
			
		||||
    event.data.group_peer_join = group_peer_join;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_peer_join_free(group_peer_join, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_peer_join;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -130,7 +130,10 @@ static Tox_Event_Group_Peer_Limit *tox_events_add_group_peer_limit(Tox_Events *e
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_PEER_LIMIT;
 | 
			
		||||
    event.data.group_peer_limit = group_peer_limit;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_peer_limit_free(group_peer_limit, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_peer_limit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,10 @@ static Tox_Event_Group_Peer_Name *tox_events_add_group_peer_name(Tox_Events *eve
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_PEER_NAME;
 | 
			
		||||
    event.data.group_peer_name = group_peer_name;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_peer_name_free(group_peer_name, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_peer_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -148,7 +148,10 @@ static Tox_Event_Group_Peer_Status *tox_events_add_group_peer_status(Tox_Events
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_PEER_STATUS;
 | 
			
		||||
    event.data.group_peer_status = group_peer_status;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_peer_status_free(group_peer_status, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_peer_status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,10 @@ static Tox_Event_Group_Privacy_State *tox_events_add_group_privacy_state(Tox_Eve
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_PRIVACY_STATE;
 | 
			
		||||
    event.data.group_privacy_state = group_privacy_state;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_privacy_state_free(group_privacy_state, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_privacy_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -209,7 +209,10 @@ static Tox_Event_Group_Private_Message *tox_events_add_group_private_message(Tox
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_PRIVATE_MESSAGE;
 | 
			
		||||
    event.data.group_private_message = group_private_message;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_private_message_free(group_private_message, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_private_message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -109,7 +109,10 @@ static Tox_Event_Group_Self_Join *tox_events_add_group_self_join(Tox_Events *eve
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_SELF_JOIN;
 | 
			
		||||
    event.data.group_self_join = group_self_join;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_self_join_free(group_self_join, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_self_join;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -175,7 +175,10 @@ static Tox_Event_Group_Topic *tox_events_add_group_topic(Tox_Events *events, con
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_TOPIC;
 | 
			
		||||
    event.data.group_topic = group_topic;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_topic_free(group_topic, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_topic;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,10 @@ static Tox_Event_Group_Topic_Lock *tox_events_add_group_topic_lock(Tox_Events *e
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_TOPIC_LOCK;
 | 
			
		||||
    event.data.group_topic_lock = group_topic_lock;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_topic_lock_free(group_topic_lock, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_topic_lock;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -132,7 +132,10 @@ static Tox_Event_Group_Voice_State *tox_events_add_group_voice_state(Tox_Events
 | 
			
		||||
    event.type = TOX_EVENT_GROUP_VOICE_STATE;
 | 
			
		||||
    event.data.group_voice_state = group_voice_state;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_group_voice_state_free(group_voice_state, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return group_voice_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -111,7 +111,10 @@ static Tox_Event_Self_Connection_Status *tox_events_add_self_connection_status(T
 | 
			
		||||
    event.type = TOX_EVENT_SELF_CONNECTION_STATUS;
 | 
			
		||||
    event.data.self_connection_status = self_connection_status;
 | 
			
		||||
 | 
			
		||||
    tox_events_add(events, &event);
 | 
			
		||||
    if (!tox_events_add(events, &event)) {
 | 
			
		||||
        tox_event_self_connection_status_free(self_connection_status, mem);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    return self_connection_status;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1032,6 +1032,11 @@ void kill_friend_connections(Friend_Connections *fr_c)
 | 
			
		||||
        kill_friend_connection(fr_c, i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // there might be allocated NONE connections
 | 
			
		||||
    if (fr_c->conns != nullptr) {
 | 
			
		||||
        free(fr_c->conns);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lan_discovery_kill(fr_c->broadcast);
 | 
			
		||||
    free(fr_c);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								external/toxcore/c-toxcore/toxcore/group.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								external/toxcore/c-toxcore/toxcore/group.c
									
									
									
									
										vendored
									
									
								
							@@ -2520,7 +2520,7 @@ static int handle_send_peers(Group_Chats *g_c, uint32_t groupnumber, const uint8
 | 
			
		||||
 | 
			
		||||
non_null(1, 3) nullable(6)
 | 
			
		||||
static void handle_direct_packet(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length,
 | 
			
		||||
                                 int connection_index, void *userdata)
 | 
			
		||||
                                 uint32_t connection_index, void *userdata)
 | 
			
		||||
{
 | 
			
		||||
    if (length == 0) {
 | 
			
		||||
        return;
 | 
			
		||||
@@ -2832,7 +2832,7 @@ static bool check_message_info(uint32_t message_number, uint8_t message_id, Grou
 | 
			
		||||
 | 
			
		||||
non_null(1, 3) nullable(6)
 | 
			
		||||
static void handle_message_packet_group(Group_Chats *g_c, uint32_t groupnumber, const uint8_t *data, uint16_t length,
 | 
			
		||||
                                        int connection_index, void *userdata)
 | 
			
		||||
                                        uint32_t connection_index, void *userdata)
 | 
			
		||||
{
 | 
			
		||||
    if (length < sizeof(uint16_t) + sizeof(uint32_t) + 1) {
 | 
			
		||||
        return;
 | 
			
		||||
 
 | 
			
		||||
@@ -8353,7 +8353,7 @@ bool gc_group_is_valid(const GC_Chat *chat)
 | 
			
		||||
/** Return true if `group_number` designates an active group in session `c`. */
 | 
			
		||||
static bool group_number_valid(const GC_Session *c, int group_number)
 | 
			
		||||
{
 | 
			
		||||
    if (group_number < 0 || group_number >= c->chats_index) {
 | 
			
		||||
    if (group_number < 0 || (uint32_t)group_number >= c->chats_index) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										161
									
								
								external/toxcore/c-toxcore/toxcore/net_crypto.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										161
									
								
								external/toxcore/c-toxcore/toxcore/net_crypto.c
									
									
									
									
										vendored
									
									
								
							@@ -122,9 +122,6 @@ typedef struct Crypto_Connection {
 | 
			
		||||
 | 
			
		||||
    bool maximum_speed_reached;
 | 
			
		||||
 | 
			
		||||
    /* Must be a pointer, because the struct is moved in memory */
 | 
			
		||||
    pthread_mutex_t *mutex;
 | 
			
		||||
 | 
			
		||||
    dht_pk_cb *dht_pk_callback;
 | 
			
		||||
    void *dht_pk_callback_object;
 | 
			
		||||
    uint32_t dht_pk_callback_number;
 | 
			
		||||
@@ -143,10 +140,6 @@ struct Net_Crypto {
 | 
			
		||||
    TCP_Connections *tcp_c;
 | 
			
		||||
 | 
			
		||||
    Crypto_Connection *crypto_connections;
 | 
			
		||||
    pthread_mutex_t tcp_mutex;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_t connections_mutex;
 | 
			
		||||
    unsigned int connection_use_counter;
 | 
			
		||||
 | 
			
		||||
    uint32_t crypto_connections_length; /* Length of connections array. */
 | 
			
		||||
 | 
			
		||||
@@ -691,7 +684,6 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
 | 
			
		||||
 | 
			
		||||
    bool direct_send_attempt = false;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(conn->mutex);
 | 
			
		||||
    const IP_Port ip_port = return_ip_port_connection(c, crypt_connection_id);
 | 
			
		||||
 | 
			
		||||
    // TODO(irungentoo): on bad networks, direct connections might not last indefinitely.
 | 
			
		||||
@@ -703,11 +695,9 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
 | 
			
		||||
 | 
			
		||||
        if (direct_connected) {
 | 
			
		||||
            if ((uint32_t)sendpacket(dht_get_net(c->dht), &ip_port, data, length) == length) {
 | 
			
		||||
                pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
                return 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
            LOGGER_WARNING(c->log, "sending packet of length %d failed", length);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
@@ -724,19 +714,12 @@ static int send_packet_to(Net_Crypto *c, int crypt_connection_id, const uint8_t
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const int ret = send_packet_tcp_connection(c->tcp_c, conn->connection_number_tcp, data, length);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(conn->mutex);
 | 
			
		||||
 | 
			
		||||
    if (ret == 0) {
 | 
			
		||||
        conn->last_tcp_sent = current_time_monotonic(c->mono_time);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
 | 
			
		||||
    if (direct_send_attempt) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
@@ -1097,7 +1080,6 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(conn->mutex);
 | 
			
		||||
    const uint16_t packet_size = 1 + sizeof(uint16_t) + length + CRYPTO_MAC_SIZE;
 | 
			
		||||
    VLA(uint8_t, packet, packet_size);
 | 
			
		||||
    packet[0] = NET_PACKET_CRYPTO_DATA;
 | 
			
		||||
@@ -1106,12 +1088,10 @@ static int send_data_packet(Net_Crypto *c, int crypt_connection_id, const uint8_
 | 
			
		||||
 | 
			
		||||
    if (len + 1 + sizeof(uint16_t) != packet_size) {
 | 
			
		||||
        LOGGER_ERROR(c->log, "encryption failed: %d", len);
 | 
			
		||||
        pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    increment_nonce(conn->sent_nonce);
 | 
			
		||||
    pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
 | 
			
		||||
    return send_packet_to(c, crypt_connection_id, packet, packet_size);
 | 
			
		||||
}
 | 
			
		||||
@@ -1207,9 +1187,7 @@ static int64_t send_lossless_packet(Net_Crypto *c, int crypt_connection_id, cons
 | 
			
		||||
    dt.sent_time = 0;
 | 
			
		||||
    dt.length = length;
 | 
			
		||||
    memcpy(dt.data, data, length);
 | 
			
		||||
    pthread_mutex_lock(conn->mutex);
 | 
			
		||||
    const int64_t packet_num = add_data_end_of_buffer(c->log, c->mem, &conn->send_array, &dt);
 | 
			
		||||
    pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
 | 
			
		||||
    if (packet_num == -1) {
 | 
			
		||||
        return -1;
 | 
			
		||||
@@ -1521,18 +1499,7 @@ static void connection_kill(Net_Crypto *c, int crypt_connection_id, void *userda
 | 
			
		||||
                                         false, userdata);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (true) { /* TODO(irungentoo): is this really the best way to do this? */
 | 
			
		||||
        pthread_mutex_lock(&c->connections_mutex);
 | 
			
		||||
 | 
			
		||||
        if (c->connection_use_counter == 0) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pthread_mutex_unlock(&c->connections_mutex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    crypto_kill(c, crypt_connection_id);
 | 
			
		||||
    pthread_mutex_unlock(&c->connections_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief Handle a received data packet.
 | 
			
		||||
@@ -1635,9 +1602,7 @@ static int handle_data_packet_core(Net_Crypto *c, int crypt_connection_id, const
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        while (true) {
 | 
			
		||||
            pthread_mutex_lock(conn->mutex);
 | 
			
		||||
            const int ret = read_data_beg_buffer(c->mem, &conn->recv_array, &dt);
 | 
			
		||||
            pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
 | 
			
		||||
            if (ret == -1) {
 | 
			
		||||
                break;
 | 
			
		||||
@@ -1835,16 +1800,6 @@ static int realloc_cryptoconnection(Net_Crypto *c, uint32_t num)
 | 
			
		||||
non_null()
 | 
			
		||||
static int create_crypto_connection(Net_Crypto *c)
 | 
			
		||||
{
 | 
			
		||||
    while (true) { /* TODO(irungentoo): is this really the best way to do this? */
 | 
			
		||||
        pthread_mutex_lock(&c->connections_mutex);
 | 
			
		||||
 | 
			
		||||
        if (c->connection_use_counter == 0) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pthread_mutex_unlock(&c->connections_mutex);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int id = -1;
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
 | 
			
		||||
@@ -1863,30 +1818,17 @@ static int create_crypto_connection(Net_Crypto *c)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (id != -1) {
 | 
			
		||||
        pthread_mutex_t *mutex = (pthread_mutex_t *)mem_alloc(c->mem, sizeof(pthread_mutex_t));
 | 
			
		||||
 | 
			
		||||
        if (mutex == nullptr) {
 | 
			
		||||
            pthread_mutex_unlock(&c->connections_mutex);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (pthread_mutex_init(mutex, nullptr) != 0) {
 | 
			
		||||
            mem_delete(c->mem, mutex);
 | 
			
		||||
            pthread_mutex_unlock(&c->connections_mutex);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Memsetting float/double to 0 is non-portable, so we explicitly set them to 0
 | 
			
		||||
        c->crypto_connections[id].packet_recv_rate = 0.0;
 | 
			
		||||
        c->crypto_connections[id].packet_send_rate = 0.0;
 | 
			
		||||
        c->crypto_connections[id].last_packets_left_rem = 0.0;
 | 
			
		||||
        c->crypto_connections[id].packet_send_rate_requested = 0.0;
 | 
			
		||||
        c->crypto_connections[id].last_packets_left_requested_rem = 0.0;
 | 
			
		||||
        c->crypto_connections[id].mutex = mutex;
 | 
			
		||||
 | 
			
		||||
        // TODO(Green-Sky): This enum is likely unneeded and the same as FREE.
 | 
			
		||||
        c->crypto_connections[id].status = CRYPTO_CONN_NO_CONNECTION;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(&c->connections_mutex);
 | 
			
		||||
    return id;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1914,8 +1856,6 @@ static int wipe_crypto_connection(Net_Crypto *c, int crypt_connection_id)
 | 
			
		||||
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_destroy(c->crypto_connections[crypt_connection_id].mutex);
 | 
			
		||||
    mem_delete(c->mem, c->crypto_connections[crypt_connection_id].mutex);
 | 
			
		||||
    crypto_memzero(&c->crypto_connections[crypt_connection_id], sizeof(Crypto_Connection));
 | 
			
		||||
 | 
			
		||||
    /* check if we can resize the connections array */
 | 
			
		||||
@@ -2098,9 +2038,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c)
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, n_c->dht_public_key, crypt_connection_id);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    if (connection_number_tcp == -1) {
 | 
			
		||||
        wipe_crypto_connection(c, crypt_connection_id);
 | 
			
		||||
@@ -2117,9 +2055,7 @@ int accept_crypto_connection(Net_Crypto *c, const New_Connection *n_c)
 | 
			
		||||
    conn->status = CRYPTO_CONN_NOT_CONFIRMED;
 | 
			
		||||
 | 
			
		||||
    if (create_send_handshake(c, crypt_connection_id, n_c->cookie, n_c->dht_public_key) != 0) {
 | 
			
		||||
        pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
        kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
 | 
			
		||||
        pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
        wipe_crypto_connection(c, crypt_connection_id);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -2155,9 +2091,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
 | 
			
		||||
 | 
			
		||||
    Crypto_Connection *conn = &c->crypto_connections[crypt_connection_id];
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const int connection_number_tcp = new_tcp_connection_to(c->tcp_c, dht_public_key, crypt_connection_id);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    if (connection_number_tcp == -1) {
 | 
			
		||||
        wipe_crypto_connection(c, crypt_connection_id);
 | 
			
		||||
@@ -2181,9 +2115,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key, const u
 | 
			
		||||
    if (create_cookie_request(c, cookie_request, conn->dht_public_key, conn->cookie_request_number,
 | 
			
		||||
                              conn->shared_key) != sizeof(cookie_request)
 | 
			
		||||
            || new_temp_packet(c, crypt_connection_id, cookie_request, sizeof(cookie_request)) != 0) {
 | 
			
		||||
        pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
        kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
 | 
			
		||||
        pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
        wipe_crypto_connection(c, crypt_connection_id);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -2241,11 +2173,7 @@ static int tcp_data_callback(void *object, int crypt_connection_id, const uint8_
 | 
			
		||||
        return tcp_handle_cookie_request(c, conn->connection_number_tcp, packet, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This unlocks the mutex that at this point is locked by do_tcp before
 | 
			
		||||
    // calling do_tcp_connections.
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
    const int ret = handle_packet_connection(c, crypt_connection_id, packet, length, false, userdata);
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    if (ret != 0) {
 | 
			
		||||
        return -1;
 | 
			
		||||
@@ -2295,10 +2223,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const int ret = add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
    return ret;
 | 
			
		||||
    return add_tcp_relay_connection(c->tcp_c, conn->connection_number_tcp, ip_port, public_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief Add a tcp relay to the array.
 | 
			
		||||
@@ -2308,10 +2233,7 @@ int add_tcp_relay_peer(Net_Crypto *c, int crypt_connection_id, const IP_Port *ip
 | 
			
		||||
 */
 | 
			
		||||
int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_key)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const int ret = add_tcp_relay_global(c->tcp_c, ip_port, public_key);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
    return ret;
 | 
			
		||||
    return add_tcp_relay_global(c->tcp_c, ip_port, public_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief Return a random TCP connection number for use in send_tcp_onion_request.
 | 
			
		||||
@@ -2322,13 +2244,9 @@ int add_tcp_relay(Net_Crypto *c, const IP_Port *ip_port, const uint8_t *public_k
 | 
			
		||||
 * return TCP connection number on success.
 | 
			
		||||
 * return -1 on failure.
 | 
			
		||||
 */
 | 
			
		||||
int get_random_tcp_con_number(Net_Crypto *c)
 | 
			
		||||
int get_random_tcp_con_number(const Net_Crypto *c)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const int ret = get_random_tcp_onion_conn_number(c->tcp_c);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
    return get_random_tcp_onion_conn_number(c->tcp_c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief Put IP_Port of a random onion TCP connection in ip_port.
 | 
			
		||||
@@ -2336,13 +2254,9 @@ int get_random_tcp_con_number(Net_Crypto *c)
 | 
			
		||||
 * return true on success.
 | 
			
		||||
 * return false on failure.
 | 
			
		||||
 */
 | 
			
		||||
bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port)
 | 
			
		||||
bool get_random_tcp_conn_ip_port(const Net_Crypto *c, IP_Port *ip_port)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const bool ret = tcp_get_random_conn_ip_port(c->tcp_c, ip_port);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
    return tcp_get_random_conn_ip_port(c->tcp_c, ip_port);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief Send an onion packet via the TCP relay corresponding to tcp_connections_number.
 | 
			
		||||
@@ -2352,11 +2266,7 @@ bool get_random_tcp_conn_ip_port(Net_Crypto *c, IP_Port *ip_port)
 | 
			
		||||
 */
 | 
			
		||||
int send_tcp_onion_request(Net_Crypto *c, unsigned int tcp_connections_number, const uint8_t *data, uint16_t length)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const int ret = tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
    return tcp_send_onion_request(c->tcp_c, tcp_connections_number, data, length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -2371,12 +2281,8 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port
 | 
			
		||||
                             const uint8_t *chain_keys, uint16_t chain_length,
 | 
			
		||||
                             const uint8_t *data, uint16_t data_length)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const int ret = tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node,
 | 
			
		||||
                    chain_keys, chain_length, data, data_length);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
    return tcp_send_forward_request(logger, c->tcp_c, tcp_forwarder, dht_node,
 | 
			
		||||
                                    chain_keys, chain_length, data, data_length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** @brief Copy a maximum of num random TCP relays we are connected to to tcp_relays.
 | 
			
		||||
@@ -2386,38 +2292,28 @@ int send_tcp_forward_request(const Logger *logger, Net_Crypto *c, const IP_Port
 | 
			
		||||
 * return number of relays copied to tcp_relays on success.
 | 
			
		||||
 * return 0 on failure.
 | 
			
		||||
 */
 | 
			
		||||
unsigned int copy_connected_tcp_relays(Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
 | 
			
		||||
unsigned int copy_connected_tcp_relays(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num)
 | 
			
		||||
{
 | 
			
		||||
    if (num == 0) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const unsigned int ret = tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
    return tcp_copy_connected_relays(c->tcp_c, tcp_relays, num);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t copy_connected_tcp_relays_index(Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx)
 | 
			
		||||
uint32_t copy_connected_tcp_relays_index(const Net_Crypto *c, Node_format *tcp_relays, uint16_t num, uint32_t idx)
 | 
			
		||||
{
 | 
			
		||||
    if (num == 0) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    const uint32_t ret = tcp_copy_connected_relays_index(c->tcp_c, tcp_relays, num, idx);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
    return tcp_copy_connected_relays_index(c->tcp_c, tcp_relays, num, idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
non_null()
 | 
			
		||||
static void do_tcp(Net_Crypto *c, void *userdata)
 | 
			
		||||
{
 | 
			
		||||
    pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
    do_tcp_connections(c->log, c->tcp_c, userdata);
 | 
			
		||||
    pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
    for (uint32_t i = 0; i < c->crypto_connections_length; ++i) {
 | 
			
		||||
        const Crypto_Connection *conn = get_crypto_connection(c, i);
 | 
			
		||||
@@ -2436,9 +2332,7 @@ static void do_tcp(Net_Crypto *c, void *userdata)
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
        set_tcp_connection_to_status(c->tcp_c, conn->connection_number_tcp, !direct_connected);
 | 
			
		||||
        pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2593,15 +2487,12 @@ static int udp_handle_packet(void *object, const IP_Port *source, const uint8_t
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(conn->mutex);
 | 
			
		||||
 | 
			
		||||
    if (net_family_is_ipv4(source->ip.family)) {
 | 
			
		||||
        conn->direct_lastrecv_timev4 = mono_time_get(c->mono_time);
 | 
			
		||||
    } else {
 | 
			
		||||
        conn->direct_lastrecv_timev6 = mono_time_get(c->mono_time);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2997,26 +2888,16 @@ int send_lossy_cryptpacket(Net_Crypto *c, int crypt_connection_id, const uint8_t
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&c->connections_mutex);
 | 
			
		||||
    ++c->connection_use_counter;
 | 
			
		||||
    pthread_mutex_unlock(&c->connections_mutex);
 | 
			
		||||
 | 
			
		||||
    Crypto_Connection *conn = get_crypto_connection(c, crypt_connection_id);
 | 
			
		||||
 | 
			
		||||
    int ret = -1;
 | 
			
		||||
 | 
			
		||||
    if (conn != nullptr) {
 | 
			
		||||
        pthread_mutex_lock(conn->mutex);
 | 
			
		||||
        const uint32_t buffer_start = conn->recv_array.buffer_start;
 | 
			
		||||
        const uint32_t buffer_end = conn->send_array.buffer_end;
 | 
			
		||||
        pthread_mutex_unlock(conn->mutex);
 | 
			
		||||
        ret = send_data_packet_helper(c, crypt_connection_id, buffer_start, buffer_end, data, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_lock(&c->connections_mutex);
 | 
			
		||||
    --c->connection_use_counter;
 | 
			
		||||
    pthread_mutex_unlock(&c->connections_mutex);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -3036,9 +2917,7 @@ int crypto_kill(Net_Crypto *c, int crypt_connection_id)
 | 
			
		||||
            send_kill_packet(c, crypt_connection_id);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        pthread_mutex_lock(&c->tcp_mutex);
 | 
			
		||||
        kill_tcp_connection_to(c->tcp_c, conn->connection_number_tcp);
 | 
			
		||||
        pthread_mutex_unlock(&c->tcp_mutex);
 | 
			
		||||
 | 
			
		||||
        bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv4, crypt_connection_id);
 | 
			
		||||
        bs_list_remove(&c->ip_port_list, (uint8_t *)&conn->ip_portv6, crypt_connection_id);
 | 
			
		||||
@@ -3135,13 +3014,6 @@ Net_Crypto *new_net_crypto(const Logger *log, const Memory *mem, const Random *r
 | 
			
		||||
    set_packet_tcp_connection_callback(temp->tcp_c, &tcp_data_callback, temp);
 | 
			
		||||
    set_oob_packet_tcp_connection_callback(temp->tcp_c, &tcp_oob_callback, temp);
 | 
			
		||||
 | 
			
		||||
    if (create_recursive_mutex(&temp->tcp_mutex) != 0 ||
 | 
			
		||||
            pthread_mutex_init(&temp->connections_mutex, nullptr) != 0) {
 | 
			
		||||
        kill_tcp_connections(temp->tcp_c);
 | 
			
		||||
        mem_delete(mem, temp);
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    temp->dht = dht;
 | 
			
		||||
 | 
			
		||||
    new_keys(temp);
 | 
			
		||||
@@ -3215,9 +3087,6 @@ void kill_net_crypto(Net_Crypto *c)
 | 
			
		||||
        crypto_kill(c, i);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pthread_mutex_destroy(&c->tcp_mutex);
 | 
			
		||||
    pthread_mutex_destroy(&c->connections_mutex);
 | 
			
		||||
 | 
			
		||||
    kill_tcp_connections(c->tcp_c);
 | 
			
		||||
    bs_list_free(&c->ip_port_list);
 | 
			
		||||
    networking_registerhandler(dht_get_net(c->dht), NET_PACKET_COOKIE_REQUEST, nullptr, nullptr);
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user