Squashed 'external/toxcore/c-toxcore/' changes from e2c01e457b..b03b571272
b03b571272 fix: flaky tcp test This only fixes the symptoms, not the real problem. Sometimes or consistently on some platforms a socket might need a moment before it can be written to. 32e67ab4c2 cleanup: use typedef for private message ID's in callback 7b1db6adc1 feat: add message IDs to private group messages 99e0bcc27d refactor: Observers/ignored peers can now send and receive custom packets b3c3c49d26 fix: Disable IPv6 in Windows cross-compilation tests e742deddff feat: Check hashes of Windows dependencies when cross-compiling dfb9a0b02b fix: Test the current Windows Dockerfile, not an old Dockerhub image 14de93ccec chore: Use WineHQ's Wine as Debian Bookworm's crashes ed37616249 docs: Update the Windows cross-compilation section 9bb79c174f cleanup: Remove a couple of unnecessary misc_tools dependencies 19475adb70 chore: Statically link OpenMP into the cracker fun util on Windows 1be311e51f feat: Build the fun utils when cross-compiling to Windows 88133f8446 chore: Strip Windows binaries 3cc0ae7535 refactor: Copy over all of the required static dependencies c4fa8f7fb1 feat: Generate .def, .exp and .lib files when building for Windows 74bbac5363 feat: Let CMake create the dll instead of doing so ourselves 246642e9ae feat: Harden Windows cross-compilation 8d431c0d11 chore: Bump Windows build dependency versions e519f7998b fix: Remove unnecessary wsock32 dependency on Windows ed2b60c217 chore: Use a specific non-broken slimcc version. d7f21010a1 chore: Update github actions. e71a68b7f2 docs: Update the list of CMake options 77e08876ff chore: Remove mod and founder from group API naming scheme 12bc042767 docs: add the experimental api build option to INSTALL.md e1fa5cae96 refactor: Rename Queries to Query to align with other enums. be82a3ea30 fix: Correct type for conference offline peer numbers. 0627c36716 test: Add pkgsrc build. 92578afe4b test: Add FreeBSD VM action on GitHub. 52ece0f57b test: Build toxcore on NetBSD (VM). 3fe8ee2c11 chore: Only install tox_private.h on request. 9a8dfa06ab fix: save_compatibility_test failing on big-endian systems 86f5e55578 fix: Don't serve files from websockify. 710eb674a5 fix: Correctly pass extended public keys to group moderation code. 021db7031c refactor: Use `struct`s for extended public/secret keys. a1e999fd80 chore: Compile libsodium reference implementation with compcert. fbe3c19cf5 cleanup: correct a few nullable annotations 623e3ee5c3 cleanup: Don't use `memcpy` to cast arbitrary `struct`s to `uint8_t[]`. c71567dc18 fix: Pass array, not array pointer, to `memcmp`. 9b46a08144 cleanup: Never pass `void*` directly to `memcpy`. 5d7b7a7bbc refactor: Use tox rng to seed the keypair generation. 961891d568 cleanup: Small improvements found by PVS Studio. 8201019f0d chore: Disable NGC saving by default, enable through Tox_Options. 5dd9ee3f65 cleanup: Replace pointer arithmetic with explicit `&arr[i]`. ca4606d49d refactor: Use strong typedef for NGC peer id. 442213b722 cleanup: Simplify custom packet length check in NGC. 08d3393def fix: Correct a few potential null derefs in bootstrap daemon. b9877b32b0 fix: Add missing memunlock of local variable when it goes out of scope. dab5fe44b9 fix: Zero out stack-allocated secret key before return. f058103299 refactor: Make prune_gc_sanctions_list more obviously correct. 3ba7a0dec9 docs: Add static analysis tool list to README. 8d0811a0f3 docs: Run prettier-markdown on markdown files. 969e3a2bfc refactor: Fix network test not using the strong typedef 93c83fbc7c refactor: Use strong typedef instead of struct for `Socket`. 9fe18b176f fix: Fix some false positive from PVS Studio. 7c44379ccb cleanup: Check that WINXP macro exists before comparing it. 5c93231bef refactor: Make tox mutex non-recursive. aacff73939 docs: Fix up doxyfile. d55fc85ff5 docs: Add more documentation to crypto_core. 5bdaaaedb6 refactor: Remove `Tox *` from `tox_dispatch`. e202341e76 refactor: Don't rely on tox_dispatch passing tox in tests. 34df938f52 chore: Use C++ mode for clang-tidy. 8b05296a78 chore: Check that both gtest and gmock exist for tests. 42010660e1 test: Add slimcc compiler compatibility test. b473630321 chore: Add some comments to the astyle config. b7404f24f6 cleanup: Remove implicit bool conversions. 4e2dba4d9f chore: Reformat sources with astyle. 4359e3a6bc chore: Rename C++ headers to .hh suffixes. 0c05566e58 cleanup: Further `#include` cleanups. 8d29935b7a chore: Only check the bootstrap daemon checksum on release. f70e588bc6 cleanup: Add more `const` where possible. 511bfe39c8 cleanup: Use Bazel modules to enforce proper `#include` hygiene. 1710a0d091 refactor: Move pack/unpack `IP_Port` from DHT into network module. a975943564 chore: Really fix coverage docker image build. c08409390f chore: Fix post-submit coverage image. 39aadf8922 fix: Don't use `memcmp` to compare `IP_Port`s. d94246a906 fix: partially fix a bug that prevented group part messages from sending. eeaa039222 chore: Fix rpm build; add a CI check for it. 8328449c1a chore: Speed up docker builds a bit by reducing layer count. d6d67d56f3 cleanup: Add `const` where possible in auto tests. 6aa9e6850d cleanup: Minor cleanup of event unpack code. bdf460a3a9 refactor: Rename `system_{memory,...}` to `os_{memory,...}`. 203e1af81e fix: a few off by one errors in group autotests 5c093c4888 cleanup: Remove all uses of `SIZEOF_VLA`. 662c2140f3 test: Add goblint static analyser. 8f07755834 cleanup: Use `memzero(x, s)` instead of `memset(x, 0, s)`. a7258e40cf cleanup: Use explicit 0 instead of `PACKET_ID_PADDING`. 6370d0f15d cleanup: Expand the `Tox_Options` accessor macros. 14a1a0b9bd cleanup: Remove plan9 support. a05dccad13 test: Add a simple new/delete test for Tox. 1cdcf938b9 cleanup: Add comment after every `#endif`. ba99d4dc4b test: Fix comment I broke in the events test PR. e07248debb refactor: Migrate auto_tests to new events API. bdd42b5452 refactor: Add common msgpack array packer with callback. 3c659f5288 cleanup: Rename group to conference in groupav documentation. 89957be230 cleanup: Ensure handler params are named after callback params. c650d9d345 refactor: Pass `this` pointer as first param to s11n callbacks. e7fb91ddb8 refactor: Allow NULL pointers for byte arrays in events. 5e2c8cabc1 cleanup: make some improvements to group moderation test 259de4867e cleanup: Remove `bin_pack_{new,free}`. 21a8ff5895 cleanup: skip a do_gc iteration before removing peers marked for deletion 16809dc36e feat: Add dht_get_nodes_response event to the events system. git-subtree-dir: external/toxcore/c-toxcore git-subtree-split: b03b5712720de9a9901ea12fd741f177327a7021
This commit is contained in:
parent
61accfe184
commit
aae086cc65
32
.cirrus.yml
32
.cirrus.yml
@ -27,6 +27,7 @@ bazel-dbg_task:
|
||||
- cd /src/workspace && bazel test -k
|
||||
--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 # TODO(robinlinden): Why does this pass locally but not in Cirrus?
|
||||
@ -47,13 +48,30 @@ cimple_task:
|
||||
//c-toxcore/...
|
||||
|
||||
freebsd_task:
|
||||
container:
|
||||
image: toxchat/freebsd:latest
|
||||
cpu: 2
|
||||
memory: 4G
|
||||
kvm: true
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-0
|
||||
configure_script:
|
||||
- PAGER=cat ASSUME_ALWAYS_YES=YES pkg install
|
||||
cmake
|
||||
git
|
||||
gmake
|
||||
googletest
|
||||
libconfig
|
||||
libsodium
|
||||
libvpx
|
||||
opus
|
||||
pkgconf
|
||||
- git submodule update --init --recursive
|
||||
- cd .. && mv cirrus-ci-build /work/c-toxcore && mkdir cirrus-ci-build
|
||||
test_all_script:
|
||||
- cd /work/c-toxcore && .github/scripts/cmake-freebsd
|
||||
- |
|
||||
# TODO(iphydf): Investigate FreeBSD failures on these tests.
|
||||
sed -Ei -e '/\(dht_getnodes_api\)/s/^/#/' auto_tests/CMakeLists.txt
|
||||
cmake . \
|
||||
-DMIN_LOGGER_LEVEL=TRACE \
|
||||
-DMUST_BUILD_TOXAV=ON \
|
||||
-DNON_HERMETIC_TESTS=ON \
|
||||
-DTEST_TIMEOUT_SECONDS=50 \
|
||||
-DUSE_IPV6=OFF \
|
||||
-DAUTOTEST=ON
|
||||
cmake --build . --target install
|
||||
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
|
||||
|
10
.clang-tidy
10
.clang-tidy
@ -21,7 +21,7 @@ CheckOptions:
|
||||
- key: readability-identifier-naming.MacroDefinitionCase
|
||||
value: UPPER_CASE
|
||||
- key: readability-identifier-naming.MacroDefinitionIgnoredRegexp
|
||||
value: "^_.*|nullable|non_null|nullptr|static_assert|ck_.*"
|
||||
value: "^_.*|bitwise|force|nullable|non_null|nullptr|static_assert|ck_.*"
|
||||
- key: readability-identifier-naming.ParameterCase
|
||||
value: lower_case
|
||||
- key: readability-identifier-naming.StructCase
|
||||
@ -36,12 +36,14 @@ CheckOptions:
|
||||
value: lower_case
|
||||
|
||||
- key: llvmlibc-restrict-system-libc-headers.Includes
|
||||
value: "arpa/inet.h,assert.h,ctype.h,errno.h,fcntl.h,getopt.h,libconfig.h,limits.h,linux/if.h,math.h,netdb.h,netinet/in.h,opus.h,pthread.h,signal.h,sodium/crypto_scalarmult_curve25519.h,sodium.h,sodium/randombytes.h,stdarg.h,stdbool.h,stddef.h,stdint.h,stdio.h,stdlib.h,string.h,sys/ioctl.h,syslog.h,sys/resource.h,sys/socket.h,sys/stat.h,sys/time.h,sys/types.h,time.h,unistd.h,vpx/vp8cx.h,vpx/vp8dx.h,vpx/vpx_decoder.h,vpx/vpx_encoder.h,vpx/vpx_image.h"
|
||||
value: "alloca.h,arpa/inet.h,assert.h,ctype.h,errno.h,fcntl.h,getopt.h,libconfig.h,limits.h,linux/if.h,math.h,netdb.h,netinet/in.h,opus.h,pthread.h,signal.h,sodium/crypto_scalarmult_curve25519.h,sodium.h,sodium/randombytes.h,stdarg.h,stdbool.h,stddef.h,stdint.h,stdio.h,stdlib.h,string.h,sys/ioctl.h,syslog.h,sys/resource.h,sys/socket.h,sys/stat.h,sys/time.h,sys/types.h,time.h,unistd.h,vpx/vp8cx.h,vpx/vp8dx.h,vpx/vpx_decoder.h,vpx/vpx_encoder.h,vpx/vpx_image.h"
|
||||
- key: hicpp-signed-bitwise.IgnorePositiveIntegerLiterals
|
||||
value: true
|
||||
- key: concurrency-mt-unsafe.FunctionSet
|
||||
value: posix
|
||||
- key: misc-include-cleaner.IgnoreHeaders
|
||||
value: "pthread.h;stdbool.h;stddef.h;stdint.;stdint.h;stdint...;cstdint;sodium.*;sys/.*;unistd.h;opus.*;vpx.*;attributes.h;tox_struct.h"
|
||||
- key: readability-function-cognitive-complexity.Threshold
|
||||
value: 153 # TODO(iphydf): Decrease. tox_new is the highest at the moment.
|
||||
- key: cppcoreguidelines-avoid-do-while.IgnoreMacros
|
||||
value: true
|
||||
- key: readability-simplify-boolean-expr.SimplifyDeMorgan
|
||||
value: false
|
||||
|
4
.github/scripts/cmake-windows.sh
vendored
4
.github/scripts/cmake-windows.sh
vendored
@ -18,7 +18,7 @@ docker run \
|
||||
-e ENABLE_ARCH_i686="$i686" \
|
||||
-e ENABLE_ARCH_x86_64="$x86_64" \
|
||||
-e ENABLE_TEST=true \
|
||||
-e EXTRA_CMAKE_FLAGS="-DBOOTSTRAP_DAEMON=OFF -DMIN_LOGGER_LEVEL=DEBUG -DTEST_TIMEOUT_SECONDS=90 -DAUTOTEST=ON" \
|
||||
-e EXTRA_CMAKE_FLAGS="-DBOOTSTRAP_DAEMON=OFF -DMIN_LOGGER_LEVEL=DEBUG -DTEST_TIMEOUT_SECONDS=90 -DAUTOTEST=ON -DUSE_IPV6=OFF" \
|
||||
-e CMAKE_C_FLAGS="$C_FLAGS" \
|
||||
-e CMAKE_CXX_FLAGS="$CXX_FLAGS" \
|
||||
-e CMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \
|
||||
@ -26,4 +26,6 @@ docker run \
|
||||
-v "$PWD:/toxcore" \
|
||||
-v "$PWD/result:/prefix" \
|
||||
--rm \
|
||||
-t \
|
||||
--pull never \
|
||||
"toxchat/windows:$WINDOWS_ARCH"
|
||||
|
3
.github/scripts/tox-bootstrapd-docker
vendored
3
.github/scripts/tox-bootstrapd-docker
vendored
@ -3,10 +3,11 @@
|
||||
set -exu -o pipefail
|
||||
|
||||
LOCAL="${1:-}"
|
||||
CHECK="${2:-}"
|
||||
|
||||
readarray -t FILES <<<"$(git ls-files)"
|
||||
|
||||
if ! tar c "${FILES[@]}" | docker build -f other/bootstrap_daemon/docker/Dockerfile -t toxchat/bootstrap-node - 2>&1 | tee docker-build.log; then
|
||||
if ! tar c "${FILES[@]}" | docker build --build-arg="CHECK=$CHECK" -f other/bootstrap_daemon/docker/Dockerfile -t toxchat/bootstrap-node - 2>&1 | tee docker-build.log; then
|
||||
grep -o "::error.*::[a-f0-9]* /usr/local/bin/tox-bootstrapd" docker-build.log
|
||||
false
|
||||
fi
|
||||
|
90
.github/workflows/ci.yml
vendored
90
.github/workflows/ci.yml
vendored
@ -15,16 +15,24 @@ jobs:
|
||||
|
||||
analysis:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, infer, misra, tcc, tokstyle]
|
||||
tool: [autotools, clang-tidy, compcert, cppcheck, doxygen, goblint, infer, freebsd, misra, modules, pkgsrc, rpm, slimcc, sparse, tcc, tokstyle]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Docker Build
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: other/docker/${{ matrix.tool }}/Dockerfile
|
||||
driver: docker
|
||||
- name: Build toxchat/c-toxcore:sources
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: other/docker/sources/sources.Dockerfile
|
||||
tags: toxchat/c-toxcore:sources
|
||||
- name: Docker Build
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: other/docker/${{ matrix.tool }}/${{ matrix.tool }}.Dockerfile
|
||||
|
||||
coverage-linux:
|
||||
runs-on: ubuntu-latest
|
||||
@ -75,7 +83,7 @@ jobs:
|
||||
- name: Build and test
|
||||
run: .github/scripts/cmake-osx
|
||||
|
||||
build-msvc:
|
||||
build-windows-msvc:
|
||||
strategy:
|
||||
matrix:
|
||||
version: [2019, 2022]
|
||||
@ -102,17 +110,77 @@ jobs:
|
||||
cd _build
|
||||
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6 --build-config Debug
|
||||
|
||||
build-windows:
|
||||
strategy:
|
||||
matrix:
|
||||
bits: [32, 64]
|
||||
build-netbsd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Cross compilation
|
||||
run: .github/scripts/cmake-win${{ matrix.bits }} script
|
||||
- name: Test in NetBSD
|
||||
id: test
|
||||
uses: vmactions/netbsd-vm@v1
|
||||
with:
|
||||
usesh: true
|
||||
copyback: false
|
||||
prepare:
|
||||
/usr/sbin/pkg_add
|
||||
cmake
|
||||
googletest
|
||||
libconfig
|
||||
libopus
|
||||
libsodium
|
||||
libvpx
|
||||
pkg-config
|
||||
|
||||
run: |
|
||||
# TODO(iphydf): Investigate NetBSD failures on these tests.
|
||||
sed -Ei -e '/\((TCP|dht_getnodes_api)\)/s/^/#/' auto_tests/CMakeLists.txt
|
||||
cmake . \
|
||||
-DMIN_LOGGER_LEVEL=TRACE \
|
||||
-DMUST_BUILD_TOXAV=ON \
|
||||
-DNON_HERMETIC_TESTS=ON \
|
||||
-DTEST_TIMEOUT_SECONDS=90 \
|
||||
-DUSE_IPV6=OFF \
|
||||
-DAUTOTEST=ON
|
||||
cmake --build . --target install
|
||||
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
|
||||
|
||||
build-freebsd:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Test in FreeBSD
|
||||
id: test
|
||||
uses: vmactions/freebsd-vm@v1
|
||||
with:
|
||||
usesh: true
|
||||
copyback: false
|
||||
prepare:
|
||||
PAGER=cat ASSUME_ALWAYS_YES=YES pkg install
|
||||
cmake
|
||||
git
|
||||
gmake
|
||||
googletest
|
||||
libconfig
|
||||
libsodium
|
||||
libvpx
|
||||
opus
|
||||
pkgconf
|
||||
|
||||
run: |
|
||||
# TODO(iphydf): Investigate FreeBSD failures on these tests.
|
||||
sed -Ei -e '/\(dht_getnodes_api\)/s/^/#/' auto_tests/CMakeLists.txt
|
||||
cmake . \
|
||||
-DMIN_LOGGER_LEVEL=TRACE \
|
||||
-DMUST_BUILD_TOXAV=ON \
|
||||
-DNON_HERMETIC_TESTS=ON \
|
||||
-DTEST_TIMEOUT_SECONDS=50 \
|
||||
-DUSE_IPV6=OFF \
|
||||
-DAUTOTEST=ON
|
||||
cmake --build . --target install
|
||||
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6
|
||||
|
||||
mypy:
|
||||
runs-on: ubuntu-latest
|
||||
|
2
.github/workflows/coverity-scan.yml
vendored
2
.github/workflows/coverity-scan.yml
vendored
@ -8,7 +8,7 @@ jobs:
|
||||
latest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install libraries
|
||||
|
73
.github/workflows/docker.yml
vendored
73
.github/workflows/docker.yml
vendored
@ -25,7 +25,9 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Docker Build
|
||||
run: .github/scripts/tox-bootstrapd-docker local
|
||||
run: .github/scripts/tox-bootstrapd-docker local "$CHECK"
|
||||
env:
|
||||
CHECK: "${{ contains(github.event.pull_request.title, 'chore: Release ') && 'sha256sum' || 'echo' }}"
|
||||
- name: Push latest image to DockerHub
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
run: docker push toxchat/bootstrap-node:latest
|
||||
@ -46,7 +48,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: "{{defaultContext}}:other/bootstrap_daemon/websocket"
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
@ -67,7 +69,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: "."
|
||||
file: .clusterfuzzlite/Dockerfile
|
||||
@ -88,7 +90,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: testing/Dockerfile
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
@ -108,7 +110,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: other/emscripten/Dockerfile
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
@ -121,21 +123,14 @@ jobs:
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
driver: docker
|
||||
- name: Login to DockerHub
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build toxchat/c-toxcore:sources
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
file: other/docker/sources/Dockerfile
|
||||
tags: toxchat/c-toxcore:sources
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: other/docker/esp32/Dockerfile
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
@ -143,9 +138,15 @@ jobs:
|
||||
cache-from: type=registry,ref=toxchat/c-toxcore:esp32
|
||||
cache-to: type=inline
|
||||
|
||||
docker-win32:
|
||||
docker-windows-mingw:
|
||||
strategy:
|
||||
matrix:
|
||||
bits: [32, 64]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to DockerHub
|
||||
@ -154,39 +155,27 @@ jobs:
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
- name: Build and store to local Docker daemon
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: "{{defaultContext}}:other/docker/windows"
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
tags: toxchat/windows:win32
|
||||
cache-from: type=registry,ref=toxchat/windows:win32
|
||||
cache-to: type=inline
|
||||
context: other/docker/windows
|
||||
load: true
|
||||
tags: toxchat/windows:win${{ matrix.bits }}
|
||||
cache-from: type=registry,ref=toxchat/windows:win${{ matrix.bits }}
|
||||
build-args: |
|
||||
SUPPORT_ARCH_i686=true
|
||||
SUPPORT_ARCH_x86_64=false
|
||||
SUPPORT_ARCH_i686=${{ matrix.bits == '32' }}
|
||||
SUPPORT_ARCH_x86_64=${{ matrix.bits == '64' }}
|
||||
SUPPORT_TEST=true
|
||||
|
||||
docker-win64:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to DockerHub
|
||||
- name: Push the stored image to Dockerhub
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: "{{defaultContext}}:other/docker/windows"
|
||||
context: other/docker/windows
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
tags: toxchat/windows:win64
|
||||
cache-from: type=registry,ref=toxchat/windows:win64
|
||||
cache-to: type=inline
|
||||
tags: toxchat/windows:win${{ matrix.bits }}
|
||||
build-args: |
|
||||
SUPPORT_ARCH_i686=false
|
||||
SUPPORT_ARCH_x86_64=true
|
||||
SUPPORT_ARCH_i686=${{ matrix.bits == '32' }}
|
||||
SUPPORT_ARCH_x86_64=${{ matrix.bits == '64' }}
|
||||
SUPPORT_TEST=true
|
||||
- name: Cross-compile
|
||||
run: .github/scripts/cmake-win${{ matrix.bits }} script
|
||||
|
10
.github/workflows/post-submit.yml
vendored
10
.github/workflows/post-submit.yml
vendored
@ -11,7 +11,7 @@ jobs:
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Docker Build
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: other/docker/alpine-s390x/Dockerfile
|
||||
|
||||
@ -29,14 +29,14 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Build toxchat/c-toxcore:sources
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: other/docker/sources/Dockerfile
|
||||
file: other/docker/sources/sources.Dockerfile
|
||||
tags: toxchat/c-toxcore:sources
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: other/docker/coverage/Dockerfile
|
||||
file: other/docker/coverage/coverage.Dockerfile
|
||||
push: ${{ github.event_name == 'push' }}
|
||||
tags: toxchat/c-toxcore:coverage
|
||||
cache-from: type=registry,ref=toxchat/c-toxcore:coverage
|
||||
|
@ -1,20 +1,25 @@
|
||||
---
|
||||
exclude:
|
||||
- "**/*.api.h"
|
||||
# shfmt doesn't support this file
|
||||
# shfmt doesn't support this file.
|
||||
- "other/analysis/run-clang-tidy"
|
||||
# Generated file.
|
||||
- "CHANGELOG.md"
|
||||
|
||||
restylers:
|
||||
- astyle:
|
||||
image: restyled/restyler-astyle:d7967bcb8b622a98524b7df1da1b02652114cf9a
|
||||
arguments: ["--options=other/astyle/astylerc"]
|
||||
include:
|
||||
- "!**/*.cc"
|
||||
- "**/*.c"
|
||||
- "**/*.h"
|
||||
- autopep8
|
||||
- black
|
||||
- clang-format:
|
||||
image: restyled/restyler-clang-format:13.0.1
|
||||
image: restyled/restyler-clang-format:v16.0.6
|
||||
include:
|
||||
- "**/*.cc"
|
||||
- "**/*.hh"
|
||||
- prettier-markdown
|
||||
- prettier-yaml
|
||||
- reorder-python-imports
|
||||
- shellharden
|
||||
|
@ -136,18 +136,20 @@ if(MIN_LOGGER_LEVEL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(EXPERIMENTAL_API "Install experimental header file with unstable API" OFF)
|
||||
|
||||
option(USE_IPV6 "Use IPv6 in tests" ON)
|
||||
if(NOT USE_IPV6)
|
||||
add_definitions(-DUSE_IPV6=0)
|
||||
endif()
|
||||
|
||||
option(BUILD_MISC_TESTS "Build additional tests and utilities" OFF)
|
||||
option(BUILD_MISC_TESTS "Build additional tests" OFF)
|
||||
option(BUILD_FUN_UTILS "Build additional just for fun utilities" OFF)
|
||||
|
||||
option(AUTOTEST "Enable autotests (mainly for CI)" OFF)
|
||||
if(AUTOTEST)
|
||||
option(NON_HERMETIC_TESTS "Whether to build and run tests that depend on an internet connection" OFF)
|
||||
option(PROXY_TEST "Enable proxy test (needs HTTP/SOCKS5 proxy on port 8080/8081)" OFF)
|
||||
option(PROXY_TEST "Enable proxy test (requires other/proxy/proxy_server.go to be running)" OFF)
|
||||
endif()
|
||||
|
||||
option(BUILD_TOXAV "Whether to build the tox AV library" ON)
|
||||
@ -223,6 +225,8 @@ set(toxcore_SOURCES
|
||||
toxcore/ccompat.h
|
||||
toxcore/crypto_core.c
|
||||
toxcore/crypto_core.h
|
||||
toxcore/crypto_core_pack.c
|
||||
toxcore/crypto_core_pack.h
|
||||
toxcore/DHT.c
|
||||
toxcore/DHT.h
|
||||
toxcore/events/conference_connected.c
|
||||
@ -231,6 +235,7 @@ set(toxcore_SOURCES
|
||||
toxcore/events/conference_peer_list_changed.c
|
||||
toxcore/events/conference_peer_name.c
|
||||
toxcore/events/conference_title.c
|
||||
toxcore/events/dht_get_nodes_response.c
|
||||
toxcore/events/events_alloc.c
|
||||
toxcore/events/events_alloc.h
|
||||
toxcore/events/file_chunk_request.c
|
||||
@ -356,8 +361,11 @@ set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} libsodium)
|
||||
set(toxcore_API_HEADERS
|
||||
${toxcore_SOURCE_DIR}/toxcore/tox.h^tox
|
||||
${toxcore_SOURCE_DIR}/toxcore/tox_events.h^tox
|
||||
${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox
|
||||
${toxcore_SOURCE_DIR}/toxcore/tox_private.h^tox)
|
||||
${toxcore_SOURCE_DIR}/toxcore/tox_dispatch.h^tox)
|
||||
if(EXPERIMENTAL_API)
|
||||
set(toxcore_API_HEADERS ${toxcore_API_HEADERS}
|
||||
${toxcore_SOURCE_DIR}/toxcore/tox_private.h^tox)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
#
|
||||
@ -446,7 +454,7 @@ elseif(TARGET Threads::Threads)
|
||||
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} Threads::Threads)
|
||||
endif()
|
||||
if(WIN32)
|
||||
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} iphlpapi wsock32 ws2_32)
|
||||
set(toxcore_LINK_LIBRARIES ${toxcore_LINK_LIBRARIES} iphlpapi ws2_32)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
@ -526,7 +534,7 @@ endfunction()
|
||||
|
||||
# The actual unit tests follow.
|
||||
#
|
||||
if(GTEST_FOUND)
|
||||
if(TARGET GTest::gtest AND TARGET GTest::gmock)
|
||||
unit_test(toxav ring_buffer)
|
||||
unit_test(toxav rtp)
|
||||
unit_test(toxcore DHT)
|
||||
|
351
INSTALL.md
351
INSTALL.md
@ -1,6 +1,8 @@
|
||||
# Installation instructions
|
||||
|
||||
These instructions will guide you through the process of building and installing the toxcore library and its components, as well as getting already pre-built binaries.
|
||||
These instructions will guide you through the process of building and installing
|
||||
the toxcore library and its components, as well as getting already pre-built
|
||||
binaries.
|
||||
|
||||
## Table of contents
|
||||
|
||||
@ -30,37 +32,44 @@ These instructions will guide you through the process of building and installing
|
||||
|
||||
#### Main
|
||||
|
||||
This repository, although called `toxcore`, in fact contains several libraries besides `toxcore` which complement it, as well as several executables. However, note that although these are separate libraries, at the moment, when building the libraries, they are all merged into a single `toxcore` library. Here is the full list of the main components that can be built using the CMake, their dependencies and descriptions.
|
||||
This repository, although called `toxcore`, in fact contains several libraries
|
||||
besides `toxcore` which complement it, as well as several executables. However,
|
||||
note that although these are separate libraries, at the moment, when building
|
||||
the libraries, they are all merged into a single `toxcore` library. Here is the
|
||||
full list of the main components that can be built using the CMake, their
|
||||
dependencies and descriptions.
|
||||
|
||||
| Name | Type | Dependencies | Platform | Description |
|
||||
|------------------|------------|------------------------------------|----------------|----------------------------------------------------------------------------|
|
||||
| `toxcore` | Library | libsodium, libm, libpthread, librt | Cross-platform | The main Tox library that provides the messenger functionality. |
|
||||
| `toxav` | Library | libtoxcore, libopus, libvpx | Cross-platform | Provides audio/video functionality. |
|
||||
| `toxencryptsave` | Library | libtoxcore, libsodium | Cross-platform | Provides encryption of Tox profiles (savedata), as well as arbitrary data. |
|
||||
| `DHT_bootstrap` | Executable | libtoxcore | Cross-platform | A simple DHT bootstrap node. |
|
||||
| `tox-bootstrapd` | Executable | libtoxcore, libconfig | Unix-like | Highly configurable DHT bootstrap node daemon (systemd, SysVinit, Docker). |
|
||||
| Name | Type | Dependencies | Platform | Description |
|
||||
| ---------------- | ---------- | ---------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `toxcore` | Library | libsodium, libm, libpthread, librt | Cross-platform | The main Tox library that provides the messenger functionality. |
|
||||
| `toxav` | Library | libtoxcore, libopus, libvpx | Cross-platform | Provides audio/video functionality. |
|
||||
| `toxencryptsave` | Library | libtoxcore, libsodium | Cross-platform | Provides encryption of Tox profiles (savedata), as well as arbitrary data. |
|
||||
| `DHT_bootstrap` | Executable | libtoxcore | Cross-platform | A simple DHT bootstrap node. |
|
||||
| `tox-bootstrapd` | Executable | libtoxcore, libconfig | Unix-like | Highly configurable DHT bootstrap node daemon (systemd, SysVinit, Docker). |
|
||||
| `cmp` | Library | | Cross-platform | C implementation of the MessagePack serialization format. [https://github.com/camgunz/cmp](https://github.com/camgunz/cmp) |
|
||||
|
||||
#### Secondary
|
||||
|
||||
There are some programs that are not built by default which you might find interesting. You need to pass `-DBUILD_FUN_UTILS=ON` to cmake to build them.
|
||||
There are some programs that are not built by default which you might find
|
||||
interesting. You need to pass `-DBUILD_FUN_UTILS=ON` to cmake to build them.
|
||||
|
||||
##### Vanity key generators
|
||||
|
||||
Can be used to generate vanity Tox Ids or DHT bootstrap node public keys.
|
||||
|
||||
| Name | Type | Dependencies | Platform | Description |
|
||||
|---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `cracker` | Executable | libsodium, OpenMP | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Multi-threaded. |
|
||||
| `cracker_simple` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Single-threaded. |
|
||||
| `strkey` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which contains a specified byte sequence at a specified or any position at all. Single-threaded. |
|
||||
| Name | Type | Dependencies | Platform | Description |
|
||||
| ---------------- | ---------- | ----------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `cracker` | Executable | libsodium, OpenMP | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Multi-threaded. |
|
||||
| `cracker_simple` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which starts with a specified byte sequence. Single-threaded. |
|
||||
| `strkey` | Executable | libsodium | Cross-platform | Tries to find a curve25519 key pair, hex representation of the public key of which contains a specified byte sequence at a specified or any position at all. Single-threaded. |
|
||||
|
||||
##### Key file generators
|
||||
|
||||
Useful for generating Tox profiles from the output of the vanity key generators, as well as generating random Tox profiles.
|
||||
Useful for generating Tox profiles from the output of the vanity key generators,
|
||||
as well as generating random Tox profiles.
|
||||
|
||||
| Name | Type | Dependencies | Platform | Description |
|
||||
|---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ------------------------- | ---------- | --------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `make-funny-savefile` | Script | python | Cross-platform | Generates a Tox profile file (savedata file) with the provided key pair. |
|
||||
| `create_bootstrap_keys` | Executable | libsodium | Cross-platform | Generates a keys file for tox-bootstrapd with either the provided or a random key pair. |
|
||||
| `create_minimal_savedata` | Executable | libsodium | Cross-platform | Generates a minimal Tox profile file (savedata file) with either the provided or a random key pair, printing the generated Tox Id and secret & public key information. |
|
||||
@ -69,10 +78,10 @@ Useful for generating Tox profiles from the output of the vanity key generators,
|
||||
|
||||
##### Other
|
||||
|
||||
| Name | Type | Dependencies | Platform | Description |
|
||||
|---------------------------|------------|-----------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `bootstrap_node_info` | Script | python3 | Cross-platform | Prints version and Message Of The Day (MOTD) information of the specified DHT bootstrap node, given the node doesn't have those disabled. |
|
||||
| `sign` | Executable | libsodium | Cross-platform | Signs a file with a ed25519 key. |
|
||||
| Name | Type | Dependencies | Platform | Description |
|
||||
| --------------------- | ---------- | ------------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `bootstrap_node_info` | Script | python3 | Cross-platform | Prints version and Message Of The Day (MOTD) information of the specified DHT bootstrap node, given the node doesn't have those disabled. |
|
||||
| `sign` | Executable | libsodium | Cross-platform | Signs a file with a ed25519 key. |
|
||||
|
||||
## Building
|
||||
|
||||
@ -80,56 +89,78 @@ Useful for generating Tox profiles from the output of the vanity key generators,
|
||||
|
||||
#### Library dependencies
|
||||
|
||||
Library dependencies are listed in the [components](#components) table. The dependencies need to be satisfied for the components to be built. Note that if you don't have a dependency for some component, e.g. you don't have `libopus` installed required for building `toxav` component, building of that component is silently disabled.
|
||||
Library dependencies are listed in the [components](#components) table. The
|
||||
dependencies need to be satisfied for the components to be built. Note that if
|
||||
you don't have a dependency for some component, e.g. you don't have `libopus`
|
||||
installed required for building `toxav` component, building of that component is
|
||||
silently disabled.
|
||||
|
||||
|
||||
Be advised that due to the addition of `cmp` as a submodule, you now also need to initialize the git submodules required by toxcore. This can be done by cloning the repo with the addition of `--recurse-submodules` or by running `git submodule update --init` in the root directory of the repo.
|
||||
Be advised that due to the addition of `cmp` as a submodule, you now also need
|
||||
to initialize the git submodules required by toxcore. This can be done by
|
||||
cloning the repo with the addition of `--recurse-submodules` or by running
|
||||
`git submodule update --init` in the root directory of the repo.
|
||||
|
||||
#### Compiler requirements
|
||||
|
||||
The supported compilers are GCC, Clang and MinGW.
|
||||
|
||||
In theory, any compiler that fully supports C99 and accepts GCC flags should work.
|
||||
In theory, any compiler that fully supports C99 and accepts GCC flags should
|
||||
work.
|
||||
|
||||
There is a partial and experimental support of Microsoft Visual C++ compiler. We welcome any patches that help improve it.
|
||||
There is a partial and experimental support of Microsoft Visual C++ compiler. We
|
||||
welcome any patches that help improve it.
|
||||
|
||||
You should have a C99 compatible compiler in order to build the main components. The secondary components might require the compiler to support GNU extensions.
|
||||
You should have a C99 compatible compiler in order to build the main components.
|
||||
The secondary components might require the compiler to support GNU extensions.
|
||||
|
||||
#### Build system requirements
|
||||
|
||||
To build the main components you need to have CMake of at least 2.8.6 version installed. You also need to have pkg-config installed, the build system uses it to find dependency libraries.
|
||||
To build the main components you need to have CMake of at least 2.8.6 version
|
||||
installed. You also need to have pkg-config installed, the build system uses it
|
||||
to find dependency libraries.
|
||||
|
||||
There is some experimental accommodation for building natively on Windows, i.e. without having to use MSYS/Cygwin and pkg-config, but it uses exact hardcoded paths for finding libraries and supports building only of some of toxcore components, so your mileage might vary.
|
||||
There is some experimental accommodation for building natively on Windows, i.e.
|
||||
without having to use MSYS/Cygwin and pkg-config, but it uses exact hardcoded
|
||||
paths for finding libraries and supports building only of some of toxcore
|
||||
components, so your mileage might vary.
|
||||
|
||||
### CMake options
|
||||
|
||||
There are some options that are available to configure the build.
|
||||
|
||||
| Name | Description | Expected Value | Default Value |
|
||||
|------------------------|-----------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------|
|
||||
| `AUTOTEST` | Enable autotests (mainly for CI). | ON or OFF | OFF |
|
||||
| `BOOTSTRAP_DAEMON` | Enable building of tox-bootstrapd, the DHT bootstrap node daemon. For Unix-like systems only. | ON or OFF | ON |
|
||||
| `BUILD_FUZZ_TESTS` | Build fuzzing harnesses. | ON or OFF | OFF |
|
||||
| `BUILD_MISC_TESTS` | Build additional tests. | ON or OFF | OFF |
|
||||
| `BUILD_FUN_UTILS` | Build additional funny utilities. | ON or OFF | OFF |
|
||||
| `BUILD_TOXAV` | Whether to build the toxav library. | ON or OFF | ON |
|
||||
| `CMAKE_INSTALL_PREFIX` | Path to where everything should be installed. | Directory path. | Platform-dependent. Refer to CMake documentation. |
|
||||
| `CMAKE_BUILD_TYPE` | Specifies the build type on single-configuration generators (e.g. make or ninja). | Debug, Release, RelWithDebInfo, MinSizeRel | Empty string. |
|
||||
| `DHT_BOOTSTRAP` | Enable building of `DHT_bootstrap` | ON or OFF | ON |
|
||||
| `ENABLE_SHARED` | Build shared (dynamic) libraries for all modules. | ON or OFF | ON |
|
||||
| `ENABLE_STATIC` | Build static libraries for all modules. | ON or OFF | ON |
|
||||
| `EXECUTION_TRACE` | Print a function trace during execution (for debugging). | ON or OFF | OFF |
|
||||
| `FULLY_STATIC` | Build fully static executables. | ON or OFF | OFF |
|
||||
| `MIN_LOGGER_LEVEL` | Logging level to use. | TRACE, DEBUG, INFO, WARNING, ERROR or nothing (empty string) for default. | Empty string. |
|
||||
| `MSVC_STATIC_SODIUM` | Whether to link libsodium statically for MSVC. | ON or OFF | OFF |
|
||||
| `MUST_BUILD_TOXAV` | Fail the build if toxav cannot be built. | ON or OFF | OFF |
|
||||
| `NON_HERMETIC_TESTS` | Whether to build and run tests that depend on an internet connection. | ON or OFF | OFF |
|
||||
| `STRICT_ABI` | Enforce strict ABI export in dynamic libraries. | ON or OFF | OFF |
|
||||
| `TEST_TIMEOUT_SECONDS` | Limit runtime of each test to the number of seconds specified. | Positive number or nothing (empty string). | Empty string. |
|
||||
| `USE_IPV6` | Use IPv6 in tests. | ON or OFF | ON |
|
||||
| Name | Description | Expected Value | Default Value |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------- |
|
||||
| `AUTOTEST` | Enable autotests (mainly for CI). | ON or OFF | OFF |
|
||||
| `BOOTSTRAP_DAEMON` | Enable building of tox-bootstrapd, the DHT bootstrap node daemon. For Unix-like systems only. | ON or OFF | ON |
|
||||
| `BUILD_FUN_UTILS` | Build additional just for fun utilities. | ON or OFF | OFF |
|
||||
| `BUILD_FUZZ_TESTS` | Build fuzzing harnesses. | ON or OFF | OFF |
|
||||
| `BUILD_MISC_TESTS` | Build additional tests. | ON or OFF | OFF |
|
||||
| `BUILD_TOXAV` | Whether to build the toxav library. | ON or OFF | ON |
|
||||
| `CMAKE_BUILD_TYPE` | Specifies the build type on single-configuration generators (e.g. make or ninja). | Debug, Release, RelWithDebInfo, MinSizeRel | Empty string. |
|
||||
| `CMAKE_INSTALL_PREFIX` | Path to where everything should be installed. | Directory path. | Platform-dependent. Refer to CMake documentation. |
|
||||
| `DHT_BOOTSTRAP` | Enable building of `DHT_bootstrap`. | ON or OFF | ON |
|
||||
| `ENABLE_SHARED` | Build shared (dynamic) libraries for all modules. | ON or OFF | ON |
|
||||
| `ENABLE_STATIC` | Build static libraries for all modules. | ON or OFF | ON |
|
||||
| `EXPERIMENTAL_API` | Install experimental header file with unstable API. | ON or OFF | OFF |
|
||||
| `FLAT_OUTPUT_STRUCTURE` | Whether to produce output artifacts in {bin,lib}. | ON or OFF | OFF |
|
||||
| `FULLY_STATIC` | Build fully static executables. | ON or OFF | OFF |
|
||||
| `MIN_LOGGER_LEVEL` | Logging level to use. | TRACE, DEBUG, INFO, WARNING, ERROR or nothing (empty string) for default. | Empty string. |
|
||||
| `MSVC_STATIC_SODIUM` | Whether to link libsodium statically for MSVC. | ON or OFF | OFF |
|
||||
| `MUST_BUILD_TOXAV` | Fail the build if toxav cannot be built. | ON or OFF | OFF |
|
||||
| `NON_HERMETIC_TESTS` | Whether to build and run tests that depend on an internet connection. | ON or OFF | OFF |
|
||||
| `PROXY_TEST` | Enable proxy test (requires `other/proxy/proxy_server.go` to be running). | ON or OFF | OFF |
|
||||
| `STRICT_ABI` | Enforce strict ABI export in dynamic libraries. | ON or OFF | OFF |
|
||||
| `TEST_TIMEOUT_SECONDS` | Limit runtime of each test to the number of seconds specified. | Positive number or nothing (empty string). | Empty string. |
|
||||
| `USE_IPV6` | Use IPv6 in tests. | ON or OFF | ON |
|
||||
|
||||
You can get this list of option using the following commands
|
||||
|
||||
```sh
|
||||
cmake -B _build -LAH
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```sh
|
||||
grep "option(" CMakeLists.txt cmake/*
|
||||
grep "set(.* CACHE" CMakeLists.txt cmake/*
|
||||
@ -150,11 +181,12 @@ cmake \
|
||||
```
|
||||
|
||||
### Building tests
|
||||
|
||||
In addition to the integration tests ("autotests") and miscellaneous tests
|
||||
enabled by cmake variables described above, there are unit tests which will be
|
||||
built if the source distribution of gtest (the Google Unit Test framework) is
|
||||
found by cmake in `c-toxcore/third_party`. This can be achieved by running
|
||||
'git clone https://github.com/google/googletest` from that directory.
|
||||
found by cmake in `c-toxcore/third_party`. This can be achieved by running 'git
|
||||
clone https://github.com/google/googletest` from that directory.
|
||||
|
||||
### Build process
|
||||
|
||||
@ -170,19 +202,33 @@ make
|
||||
make install
|
||||
```
|
||||
|
||||
or shorter
|
||||
|
||||
```sh
|
||||
cmake -B _build
|
||||
cmake -B _build --target install
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
##### Building on Windows host
|
||||
|
||||
###### Microsoft Visual Studio's Developer Command Prompt
|
||||
|
||||
In addition to meeting the [requirements](#requirements), you need a version of Visual Studio (the [community edition](https://www.visualstudio.com/vs/visual-studio-express/) is enough) and a CMake version that's compatible with the Visual Studio version you're using.
|
||||
In addition to meeting the [requirements](#requirements), you need a version of
|
||||
Visual Studio (the
|
||||
[community edition](https://www.visualstudio.com/vs/visual-studio-express/) is
|
||||
enough) and a CMake version that's compatible with the Visual Studio version
|
||||
you're using.
|
||||
|
||||
You must also ensure that the msvc versions of dependencies you're using are placed in the correct folders.
|
||||
You must also ensure that the msvc versions of dependencies you're using are
|
||||
placed in the correct folders.
|
||||
|
||||
For libsodium that is `c-toxcore/third_party/libsodium`, and for pthreads-w32, it's `c-toxcore/third_party/pthreads-win32`
|
||||
For libsodium that is `c-toxcore/third_party/libsodium`, and for pthreads-w32,
|
||||
it's `c-toxcore/third_party/pthreads-win32`
|
||||
|
||||
Once all of this is done, from the **Developer Command Prompt for VS**, simply run
|
||||
Once all of this is done, from the **Developer Command Prompt for VS**, simply
|
||||
run
|
||||
|
||||
```
|
||||
mkdir _build
|
||||
@ -193,22 +239,23 @@ msbuild ALL_BUILD.vcxproj
|
||||
|
||||
###### MSYS/Cygwin
|
||||
|
||||
Download Cygwin ([32-bit](https://cygwin.com/setup-x86.exe)/[64-bit](https://cygwin.com/setup-x86_64.exe))
|
||||
Download Cygwin
|
||||
([32-bit](https://cygwin.com/setup-x86.exe)/[64-bit](https://cygwin.com/setup-x86_64.exe))
|
||||
|
||||
Search and select exactly these packages in Devel category:
|
||||
|
||||
- mingw64-i686-gcc-core (32-bit) / mingw64-x86_64-gcc-core (64-bit)
|
||||
- mingw64-i686-gcc-g++ (32-bit) / mingw64-x86_64-gcc-g++ (64-bit)
|
||||
- make
|
||||
- cmake
|
||||
- libtool
|
||||
- autoconf
|
||||
- automake
|
||||
- tree
|
||||
- curl
|
||||
- perl
|
||||
- yasm
|
||||
- pkg-config
|
||||
- mingw64-i686-gcc-core (32-bit) / mingw64-x86_64-gcc-core (64-bit)
|
||||
- mingw64-i686-gcc-g++ (32-bit) / mingw64-x86_64-gcc-g++ (64-bit)
|
||||
- make
|
||||
- cmake
|
||||
- libtool
|
||||
- autoconf
|
||||
- automake
|
||||
- tree
|
||||
- curl
|
||||
- perl
|
||||
- yasm
|
||||
- pkg-config
|
||||
|
||||
To handle Windows EOL correctly run the following in the Cygwin Terminal:
|
||||
|
||||
@ -221,18 +268,24 @@ set -o igncr
|
||||
|
||||
Download toxcore source code and extract it to a folder.
|
||||
|
||||
Open Cygwin Terminal in the toxcore folder and run `./other/windows_build_script_toxcore.sh` to start the build process.
|
||||
Open Cygwin Terminal in the toxcore folder and run
|
||||
`./other/windows_build_script_toxcore.sh` to start the build process.
|
||||
|
||||
Toxcore build result files will appear in `/root/prefix/` relatively to Cygwin folder (default `C:\cygwin64`).
|
||||
|
||||
Dependency versions can be customized in `./other/windows_build_script_toxcore.sh` and described in the section below.
|
||||
Toxcore build result files will appear in `/root/prefix/` relatively to Cygwin
|
||||
folder (default `C:\cygwin64`).
|
||||
|
||||
Dependency versions can be customized in
|
||||
`./other/windows_build_script_toxcore.sh` and described in the section below.
|
||||
|
||||
##### Cross-compiling from Linux
|
||||
|
||||
These cross-compilation instructions were tested on and written for 64-bit Ubuntu 16.04. You could generalize them for any Linux system, the only requirements are that you have Docker version of >= 1.9.0 and you are running 64-bit system.
|
||||
These cross-compilation instructions were tested on and written for 64-bit
|
||||
Ubuntu 16.04. You could generalize them for any Linux system, the only
|
||||
requirements are that you have Docker version of >= 1.9.0 and you are running
|
||||
64-bit system.
|
||||
|
||||
The cross-compilation is fully automated by a parameterized [Dockerfile](/other/docker/windows/Dockerfile).
|
||||
The cross-compilation is fully automated by a parameterized
|
||||
[Dockerfile](/other/docker/windows/Dockerfile).
|
||||
|
||||
Install Docker
|
||||
|
||||
@ -243,17 +296,18 @@ apt-get install docker.io
|
||||
|
||||
Get the toxcore source code and navigate to `other/docker/windows`.
|
||||
|
||||
Build the container image based on the Dockerfile. The following options are available to customize the building of the container image.
|
||||
Build the container image based on the Dockerfile. The following options are
|
||||
available to customize the building of the container image.
|
||||
|
||||
| Name | Description | Expected Value | Default Value |
|
||||
|-----------------------|----------------------------------------------------------------|-------------------------------------|---------------|
|
||||
| `SUPPORT_ARCH_i686` | Support building 32-bit toxcore. | "true" or "false" (case sensitive). | true |
|
||||
| `SUPPORT_ARCH_x86_64` | Support building 64-bit toxcore. | "true" or "false" (case sensitive). | true |
|
||||
| `SUPPORT_TEST` | Support running toxcore automated tests. | "true" or "false" (case sensitive). | false |
|
||||
| `CROSS_COMPILE` | Cross-compiling. True for Docker, false for Cygwin. | "true" or "false" (case sensitive). | true |
|
||||
| `VERSION_OPUS` | Version of libopus to build toxcore with. | Numeric version number. | 1.3.1 |
|
||||
| `VERSION_SODIUM` | Version of libsodium to build toxcore with. | Numeric version number. | 1.0.18 |
|
||||
| `VERSION_VPX` | Version of libvpx to build toxcore with. | Numeric version number. | 1.11.0 |
|
||||
| Name | Description | Expected Value | Default Value |
|
||||
| -------------------------- | ----------------------------------------------------- | ----------------------------------- | ------------- |
|
||||
| `SUPPORT_ARCH_i686` | Support building 32-bit toxcore. | "true" or "false" (case sensitive). | true |
|
||||
| `SUPPORT_ARCH_x86_64` | Support building 64-bit toxcore. | "true" or "false" (case sensitive). | true |
|
||||
| `SUPPORT_TEST` | Support running toxcore automated tests. | "true" or "false" (case sensitive). | false |
|
||||
| `VERSION_OPUS` | Version of libopus to build toxcore with. | Numeric version number. | 1.4 |
|
||||
| `VERSION_SODIUM` | Version of libsodium to build toxcore with. | Numeric version number. | 1.0.19 |
|
||||
| `VERSION_VPX` | Version of libvpx to build toxcore with. | Numeric version number. | 1.14.0 |
|
||||
| `ENABLE_HASH_VERIFICATION` | Verify the hashes of the default dependency versions. | "true" or "false" (case sensitive). | true |
|
||||
|
||||
Example of building a container image with options
|
||||
|
||||
@ -265,16 +319,16 @@ docker build \
|
||||
.
|
||||
```
|
||||
|
||||
Run the container to build toxcore. The following options are available to customize the running of the container image.
|
||||
Run the container to build toxcore. The following options are available to
|
||||
customize the running of the container image.
|
||||
|
||||
| Name | Description | Expected Value | Default Value |
|
||||
|----------------------|--------------------------------------------------------------------------------------------|-------------------------------------|--------------------------------------------------------------------|
|
||||
| `ALLOW_TEST_FAILURE` | Don't stop if a test suite fails. | "true" or "false" (case sensitive). | `false` |
|
||||
| `ENABLE_ARCH_i686` | Build 32-bit toxcore. The image should have been built with `SUPPORT_ARCH_i686` enabled. | "true" or "false" (case sensitive). | `true` |
|
||||
| `ENABLE_ARCH_x86_64` | Build 64-bit toxcore. The image should have been built with `SUPPORT_ARCH_x86_64` enabled. | "true" or "false" (case sensitive). | `true` |
|
||||
| `ENABLE_TEST` | Run the test suite. The image should have been built with `SUPPORT_TEST` enabled. | "true" or "false" (case sensitive). | `false` |
|
||||
| `EXTRA_CMAKE_FLAGS` | Extra arguments to pass to the CMake command when building toxcore. | CMake options. | `-DTEST_TIMEOUT_SECONDS=90` |
|
||||
| `CROSS_COMPILE` | Cross-compiling. True for Docker, false for Cygwin. | "true" or "false" (case sensitive). | `true` |
|
||||
| Name | Description | Expected Value | Default Value |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------- | ------------------------------------------ |
|
||||
| `ALLOW_TEST_FAILURE` | Don't stop if a test suite fails. | "true" or "false" (case sensitive). | `false` |
|
||||
| `ENABLE_ARCH_i686` | Build 32-bit toxcore. The image should have been built with `SUPPORT_ARCH_i686` enabled. | "true" or "false" (case sensitive). | `true` |
|
||||
| `ENABLE_ARCH_x86_64` | Build 64-bit toxcore. The image should have been built with `SUPPORT_ARCH_x86_64` enabled. | "true" or "false" (case sensitive). | `true` |
|
||||
| `ENABLE_TEST` | Run the test suite. The image should have been built with `SUPPORT_TEST` enabled. | "true" or "false" (case sensitive). | `false` |
|
||||
| `EXTRA_CMAKE_FLAGS` | Extra arguments to pass to the CMake command when building toxcore. | CMake options. | `-DTEST_TIMEOUT_SECONDS=90 -DUSE_IPV6=OFF` |
|
||||
|
||||
Example of running the container with options
|
||||
|
||||
@ -284,14 +338,117 @@ docker run \
|
||||
-e ALLOW_TEST_FAILURE=true \
|
||||
-v /path/to/toxcore/sourcecode:/toxcore \
|
||||
-v /path/to/where/output/build/result:/prefix \
|
||||
-t \
|
||||
--rm \
|
||||
toxcore
|
||||
```
|
||||
|
||||
After the build succeeds, you should see the built toxcore libraries in `/path/to/where/output/build/result`.
|
||||
After the build succeeds, you should see the built toxcore libraries in
|
||||
`/path/to/where/output/build/result`.
|
||||
|
||||
The file structure should look similar to the following
|
||||
|
||||
```
|
||||
result
|
||||
├── [4.0K] i686
|
||||
│ ├── [ 36K] bin
|
||||
│ │ ├── [636K] DHT_bootstrap.exe
|
||||
│ │ ├── [572K] cracker.exe
|
||||
│ │ ├── [359K] cracker_simple.exe
|
||||
│ │ ├── [378K] create_bootstrap_keys.exe
|
||||
│ │ ├── [378K] create_minimal_savedata.exe
|
||||
│ │ ├── [958K] create_savedata.exe
|
||||
│ │ ├── [ 18K] libtoxcore.def
|
||||
│ │ ├── [2.6M] libtoxcore.dll
|
||||
│ │ ├── [ 65K] libtoxcore.exp
|
||||
│ │ ├── [428K] libtoxcore.lib
|
||||
│ │ ├── [989K] save-generator.exe
|
||||
│ │ ├── [381K] sign.exe
|
||||
│ │ └── [408K] strkey.exe
|
||||
│ ├── [4.0K] include
|
||||
│ │ └── [4.0K] tox
|
||||
│ │ ├── [177K] tox.h
|
||||
│ │ ├── [ 10K] tox_dispatch.h
|
||||
│ │ ├── [ 26K] tox_events.h
|
||||
│ │ ├── [6.4K] tox_private.h
|
||||
│ │ ├── [ 26K] toxav.h
|
||||
│ │ └── [ 12K] toxencryptsave.h
|
||||
│ └── [4.0K] lib
|
||||
│ ├── [577K] libopus.a
|
||||
│ ├── [660K] libsodium.a
|
||||
│ ├── [ 10K] libssp.a
|
||||
│ ├── [1016K] libtoxcore.a
|
||||
│ ├── [456K] libtoxcore.dll.a
|
||||
│ ├── [2.7M] libvpx.a
|
||||
│ ├── [ 72K] libwinpthread.a
|
||||
│ └── [4.0K] pkgconfig
|
||||
│ ├── [ 250] libsodium.pc
|
||||
│ ├── [ 357] opus.pc
|
||||
│ ├── [ 247] toxcore.pc
|
||||
│ └── [ 309] vpx.pc
|
||||
└── [4.0K] x86_64
|
||||
├── [ 36K] bin
|
||||
│ ├── [504K] DHT_bootstrap.exe
|
||||
│ ├── [474K] cracker.exe
|
||||
│ ├── [277K] cracker_simple.exe
|
||||
│ ├── [287K] create_bootstrap_keys.exe
|
||||
│ ├── [288K] create_minimal_savedata.exe
|
||||
│ ├── [769K] create_savedata.exe
|
||||
│ ├── [ 18K] libtoxcore.def
|
||||
│ ├── [2.4M] libtoxcore.dll
|
||||
│ ├── [ 64K] libtoxcore.exp
|
||||
│ ├── [420K] libtoxcore.lib
|
||||
│ ├── [800K] save-generator.exe
|
||||
│ ├── [289K] sign.exe
|
||||
│ └── [317K] strkey.exe
|
||||
├── [4.0K] include
|
||||
│ └── [4.0K] tox
|
||||
│ ├── [177K] tox.h
|
||||
│ ├── [ 10K] tox_dispatch.h
|
||||
│ ├── [ 26K] tox_events.h
|
||||
│ ├── [6.4K] tox_private.h
|
||||
│ ├── [ 26K] toxav.h
|
||||
│ └── [ 12K] toxencryptsave.h
|
||||
└── [4.0K] lib
|
||||
├── [697K] libopus.a
|
||||
├── [575K] libsodium.a
|
||||
├── [ 11K] libssp.a
|
||||
├── [905K] libtoxcore.a
|
||||
├── [449K] libtoxcore.dll.a
|
||||
├── [2.9M] libvpx.a
|
||||
├── [ 68K] libwinpthread.a
|
||||
└── [4.0K] pkgconfig
|
||||
├── [ 252] libsodium.pc
|
||||
├── [ 359] opus.pc
|
||||
├── [ 249] toxcore.pc
|
||||
└── [ 311] vpx.pc
|
||||
|
||||
12 directories, 60 files
|
||||
```
|
||||
|
||||
- `libtoxcore.dll` is the shared library. It is fully self-contained, with no
|
||||
additional dependencies aside from the Windows OS dlls, and can be used in
|
||||
MSVC, MinGW, Clang, etc. projects. Despite its name, it provides toxcore,
|
||||
toxav, toxencryptsave -- all of Tox.
|
||||
- `libtoxcore.a` is the static library. In order to use it, it needs to be
|
||||
linked against the other provided .a libraries (but not the .dll.a!) and
|
||||
additionally -liphlpapi and -lws2_32 Windows dlls. It similarly provides all
|
||||
of Tox APIs.
|
||||
- `libtoxcore.dll.a` is the MinGW import library for `libtoxcore.dll`.
|
||||
- `libtoxcore.lib` is the MSVC import library for `libtoxcore.dll`.
|
||||
- `libtoxcore.exp` and `libtoxcore.def` are the exported by `libtoxcore`
|
||||
symbols.
|
||||
- `*.exe` are statically compiled executables -- `DHT_bootstrap` and
|
||||
[the fun utils](#secondary).
|
||||
|
||||
## Pre-built binaries
|
||||
|
||||
### Linux
|
||||
|
||||
Toxcore is packaged by at least by the following distributions: ALT Linux, [Arch Linux](https://www.archlinux.org/packages/?q=toxcore), [Fedora](https://apps.fedoraproject.org/packages/toxcore), Mageia, openSUSE, PCLinuxOS, ROSA and Slackware, [according to the information from pkgs.org](https://pkgs.org/download/toxcore). Note that this list might be incomplete and some other distributions might package it too.
|
||||
Toxcore is packaged by at least by the following distributions: ALT Linux,
|
||||
[Arch Linux](https://www.archlinux.org/packages/?q=toxcore),
|
||||
[Fedora](https://apps.fedoraproject.org/packages/toxcore), Mageia, openSUSE,
|
||||
PCLinuxOS, ROSA and Slackware,
|
||||
[according to the information from pkgs.org](https://pkgs.org/download/toxcore).
|
||||
Note that this list might be incomplete and some other distributions might
|
||||
package it too.
|
||||
|
71
README.md
71
README.md
@ -1,8 +1,14 @@
|
||||
# ![Project Tox](https://raw.github.com/TokTok/c-toxcore/master/other/tox.png "Project Tox")
|
||||
|
||||
**Current Coverage:** [![coverage](https://codecov.io/gh/TokTok/c-toxcore/branch/master/graph/badge.svg?token=BRfCKo02De)](https://codecov.io/gh/TokTok/c-toxcore)
|
||||
**Current Coverage:**
|
||||
[![coverage](https://codecov.io/gh/TokTok/c-toxcore/branch/master/graph/badge.svg?token=BRfCKo02De)](https://codecov.io/gh/TokTok/c-toxcore)
|
||||
|
||||
[**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|** [**Blog**](https://blog.tox.chat/) **|** [**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|** [**Binaries/Downloads**](https://tox.chat/download.html) **|** [**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|** [**Compiling**](/INSTALL.md)
|
||||
[**Website**](https://tox.chat) **|** [**Wiki**](https://wiki.tox.chat/) **|**
|
||||
[**Blog**](https://blog.tox.chat/) **|**
|
||||
[**FAQ**](https://wiki.tox.chat/doku.php?id=users:faq) **|**
|
||||
[**Binaries/Downloads**](https://tox.chat/download.html) **|**
|
||||
[**Clients**](https://wiki.tox.chat/doku.php?id=clients) **|**
|
||||
[**Compiling**](/INSTALL.md)
|
||||
|
||||
## What is Tox
|
||||
|
||||
@ -16,29 +22,33 @@ and privacy easy to obtain for regular users. It uses
|
||||
### ![Danger: Experimental](other/tox-warning.png)
|
||||
|
||||
This is an **experimental** cryptographic network library. It has not been
|
||||
formally audited by an independent third party that specializes in
|
||||
cryptography or cryptanalysis. **Use this library at your own risk.**
|
||||
formally audited by an independent third party that specializes in cryptography
|
||||
or cryptanalysis. **Use this library at your own risk.**
|
||||
|
||||
The underlying crypto library [libsodium](https://doc.libsodium.org/) provides
|
||||
reliable encryption, but the security model has not yet been fully specified.
|
||||
See [issue 210](https://github.com/TokTok/c-toxcore/issues/210) for a
|
||||
discussion on developing a threat model. See other issues for known weaknesses
|
||||
(e.g. [issue 426](https://github.com/TokTok/c-toxcore/issues/426) describes
|
||||
what can happen if your secret key is stolen).
|
||||
See [issue 210](https://github.com/TokTok/c-toxcore/issues/210) for a discussion
|
||||
on developing a threat model. See other issues for known weaknesses (e.g.
|
||||
[issue 426](https://github.com/TokTok/c-toxcore/issues/426) describes what can
|
||||
happen if your secret key is stolen).
|
||||
|
||||
## Toxcore Development Roadmap
|
||||
|
||||
The roadmap and changelog are generated from GitHub issues. You may view them
|
||||
on the website, where they are updated at least once every 24 hours:
|
||||
The roadmap and changelog are generated from GitHub issues. You may view them on
|
||||
the website, where they are updated at least once every 24 hours:
|
||||
|
||||
- Changelog: https://toktok.ltd/changelog/c-toxcore
|
||||
- Roadmap: https://toktok.ltd/roadmap/c-toxcore
|
||||
- Changelog: https://toktok.ltd/changelog/c-toxcore
|
||||
- Roadmap: https://toktok.ltd/roadmap/c-toxcore
|
||||
|
||||
## Installing toxcore
|
||||
|
||||
Detailed installation instructions can be found in [INSTALL.md](INSTALL.md).
|
||||
|
||||
Be advised that due to the addition of `cmp` as a submodule, you now also need to initialize the git submodules required by toxcore. This can be done by cloning the repo with the following command: `git clone --recurse-submodules https://github.com/Toktok/c-toxcore` or by running `git submodule update --init` in the root directory of the repo.
|
||||
Be advised that due to the addition of `cmp` as a submodule, you now also need
|
||||
to initialize the git submodules required by toxcore. This can be done by
|
||||
cloning the repo with the following command:
|
||||
`git clone --recurse-submodules https://github.com/Toktok/c-toxcore` or by
|
||||
running `git submodule update --init` in the root directory of the repo.
|
||||
|
||||
In a nutshell, if you have [libsodium](https://github.com/jedisct1/libsodium)
|
||||
installed, run:
|
||||
@ -74,17 +84,17 @@ if (err_new != TOX_ERR_NEW_OK) {
|
||||
}
|
||||
```
|
||||
|
||||
Here, we simply exit the program, but in a real client you will probably want
|
||||
to do some error handling and proper error reporting to the user. The `NULL`
|
||||
Here, we simply exit the program, but in a real client you will probably want to
|
||||
do some error handling and proper error reporting to the user. The `NULL`
|
||||
argument given to the first parameter of `tox_new` is the `Tox_Options`. It
|
||||
contains various write-once network settings and allows you to load a
|
||||
previously serialised instance. See [toxcore/tox.h](tox.h) for details.
|
||||
contains various write-once network settings and allows you to load a previously
|
||||
serialised instance. See [toxcore/tox.h](tox.h) for details.
|
||||
|
||||
### Setting up callbacks
|
||||
|
||||
Toxcore works with callbacks that you can register to listen for certain
|
||||
events. Examples of such events are "friend request received" or "friend sent
|
||||
a message". Search the API for `tox_callback_*` to find all of them.
|
||||
Toxcore works with callbacks that you can register to listen for certain events.
|
||||
Examples of such events are "friend request received" or "friend sent a
|
||||
message". Search the API for `tox_callback_*` to find all of them.
|
||||
|
||||
Here, we will set up callbacks for receiving friend requests and receiving
|
||||
messages. We will always accept any friend request (because we're a bot), and
|
||||
@ -172,3 +182,24 @@ the API documentation in [toxcore/tox.h](toxcore/tox.h) for more information.
|
||||
|
||||
- [Another echo bot](https://wiki.tox.chat/developers/client_examples/echo_bot)
|
||||
- [minitox](https://github.com/hqwrong/minitox) (A minimal tox client)
|
||||
|
||||
## SAST Tools
|
||||
|
||||
This project uses various tools supporting Static Application Security Testing:
|
||||
|
||||
- [clang-tidy](https://clang.llvm.org/extra/clang-tidy/): A clang-based C++
|
||||
"linter" tool.
|
||||
- [Coverity](https://scan.coverity.com/): A cloud-based static analyzer service
|
||||
for Java, C/C++, C#, JavaScript, Ruby, or Python that is free for open source
|
||||
projects.
|
||||
- [cppcheck](https://cppcheck.sourceforge.io/): A static analyzer for C/C++
|
||||
code.
|
||||
- [cpplint](https://github.com/cpplint/cpplint): Static code checker for C++
|
||||
- [goblint](https://goblint.in.tum.de/): A static analyzer for multi-threaded C
|
||||
programs, specializing in finding concurrency bugs.
|
||||
- [infer](https://github.com/facebook/infer): A static analyzer for Java, C,
|
||||
C++, and Objective-C.
|
||||
- [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source):
|
||||
A static analyzer for C, C++, C#, and Java code.
|
||||
- [tokstyle](https://github.com/TokTok/hs-tokstyle): A style checker for TokTok
|
||||
C projects.
|
||||
|
@ -17,6 +17,8 @@ cc_library(
|
||||
"//c-toxcore/toxcore:Messenger",
|
||||
"//c-toxcore/toxcore:mono_time",
|
||||
"//c-toxcore/toxcore:tox",
|
||||
"//c-toxcore/toxcore:tox_dispatch",
|
||||
"//c-toxcore/toxcore:tox_events",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -240,6 +240,7 @@ endif
|
||||
|
||||
|
||||
EXTRA_DIST += \
|
||||
$(top_srcdir)/auto_tests/data/save.tox \
|
||||
$(top_srcdir)/auto_tests/data/save.tox.big \
|
||||
$(top_srcdir)/auto_tests/data/save.tox.little \
|
||||
$(top_srcdir)/auto_tests/check_compat.h \
|
||||
$(top_srcdir)/auto_tests/auto_test_support.h
|
||||
|
@ -45,11 +45,11 @@ static uint16_t ports[NUM_PORTS] = {13215, 33445, 25643};
|
||||
|
||||
static void test_basic(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
@ -266,13 +266,14 @@ static void kill_tcp_con(struct sec_TCP_con *con)
|
||||
static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP_con *con, const uint8_t *data,
|
||||
uint16_t length)
|
||||
{
|
||||
VLA(uint8_t, packet, sizeof(uint16_t) + length + CRYPTO_MAC_SIZE);
|
||||
const uint16_t packet_size = sizeof(uint16_t) + length + CRYPTO_MAC_SIZE;
|
||||
VLA(uint8_t, packet, packet_size);
|
||||
|
||||
uint16_t c_length = net_htons(length + CRYPTO_MAC_SIZE);
|
||||
memcpy(packet, &c_length, sizeof(uint16_t));
|
||||
int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t));
|
||||
|
||||
if ((unsigned int)len != (SIZEOF_VLA(packet) - sizeof(uint16_t))) {
|
||||
if ((unsigned int)len != (packet_size - sizeof(uint16_t))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -282,7 +283,7 @@ static int write_packet_tcp_test_connection(const Logger *logger, struct sec_TCP
|
||||
localhost.ip = get_loopback();
|
||||
localhost.port = 0;
|
||||
|
||||
ck_assert_msg(net_send(con->ns, logger, con->sock, packet, SIZEOF_VLA(packet), &localhost) == SIZEOF_VLA(packet),
|
||||
ck_assert_msg(net_send(con->ns, logger, con->sock, packet, packet_size, &localhost) == packet_size,
|
||||
"Failed to send a packet.");
|
||||
return 0;
|
||||
}
|
||||
@ -303,11 +304,11 @@ static int read_packet_sec_tcp(const Logger *logger, struct sec_TCP_con *con, ui
|
||||
|
||||
static void test_some(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
@ -498,11 +499,11 @@ static int oob_data_callback(void *object, const uint8_t *public_key, const uint
|
||||
|
||||
static void test_client(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
|
||||
Logger *logger = logger_new();
|
||||
@ -524,8 +525,9 @@ static void test_client(void)
|
||||
ip_port_tcp_s.ip = get_loopback();
|
||||
|
||||
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f_public_key, f_secret_key, nullptr);
|
||||
do_tcp_connection(logger, mono_time, conn, nullptr);
|
||||
// TCP sockets might need a moment before they can be written to.
|
||||
c_sleep(50);
|
||||
do_tcp_connection(logger, mono_time, conn, nullptr);
|
||||
|
||||
// The connection status should be unconfirmed here because we have finished
|
||||
// sending our data and are awaiting a response.
|
||||
@ -559,6 +561,7 @@ static void test_client(void)
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
TCP_Client_Connection *conn2 = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s, self_public_key, f2_public_key,
|
||||
f2_secret_key, nullptr);
|
||||
c_sleep(50);
|
||||
|
||||
// The client should call this function (defined earlier) during the routing process.
|
||||
routing_response_handler(conn, response_callback, (char *)conn + 2);
|
||||
@ -581,7 +584,7 @@ static void test_client(void)
|
||||
do_tcp_connection(logger, mono_time, conn2, nullptr);
|
||||
c_sleep(50);
|
||||
|
||||
uint8_t data[5] = {1, 2, 3, 4, 5};
|
||||
const uint8_t data[5] = {1, 2, 3, 4, 5};
|
||||
memcpy(oob_pubkey, f2_public_key, CRYPTO_PUBLIC_KEY_SIZE);
|
||||
send_oob_packet(logger, conn2, f_public_key, data, 5);
|
||||
send_routing_request(logger, conn, f2_public_key);
|
||||
@ -632,11 +635,11 @@ static void test_client(void)
|
||||
// Test how the client handles servers that don't respond.
|
||||
static void test_client_invalid(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
@ -654,7 +657,7 @@ static void test_client_invalid(void)
|
||||
ip_port_tcp_s.port = net_htons(ports[random_u32(rng) % NUM_PORTS]);
|
||||
ip_port_tcp_s.ip = get_loopback();
|
||||
TCP_Client_Connection *conn = new_tcp_connection(logger, mem, mono_time, rng, ns, &ip_port_tcp_s,
|
||||
self_public_key, f_public_key, f_secret_key, nullptr);
|
||||
self_public_key, f_public_key, f_secret_key, nullptr);
|
||||
|
||||
// Run the client's main loop but not the server.
|
||||
mono_time_update(mono_time);
|
||||
@ -708,14 +711,13 @@ static int tcp_data_callback(void *object, int id, const uint8_t *data, uint16_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void test_tcp_connection(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
@ -824,11 +826,11 @@ static int tcp_oobdata_callback(void *object, const uint8_t *public_key, unsigne
|
||||
|
||||
static void test_tcp_connection2(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
static void test_bucketnum(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
uint8_t key1[CRYPTO_PUBLIC_KEY_SIZE], key2[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
random_bytes(rng, key1, sizeof(key1));
|
||||
@ -50,11 +50,11 @@ static void test_announce_data(void *object, const uint8_t *data, uint16_t lengt
|
||||
|
||||
static void test_store_data(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
|
||||
Logger *log = logger_new();
|
||||
@ -120,7 +120,6 @@ static void basic_announce_tests(void)
|
||||
test_store_data();
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include "../testing/misc_tools.h"
|
||||
#include "../toxcore/Messenger.h"
|
||||
#include "../toxcore/mono_time.h"
|
||||
#include "../toxcore/tox_dispatch.h"
|
||||
#include "../toxcore/tox_events.h"
|
||||
#include "../toxcore/tox_struct.h"
|
||||
|
||||
#include "auto_test_support.h"
|
||||
@ -23,6 +25,7 @@ Run_Auto_Options default_run_auto_options(void)
|
||||
.graph = GRAPH_COMPLETE,
|
||||
.init_autotox = nullptr,
|
||||
.tcp_port = 33188,
|
||||
.events = true,
|
||||
};
|
||||
}
|
||||
|
||||
@ -131,7 +134,15 @@ void iterate_all_wait(AutoTox *autotoxes, uint32_t tox_count, uint32_t wait)
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
if (autotoxes[i].alive) {
|
||||
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
||||
if (autotoxes[i].events) {
|
||||
Tox_Err_Events_Iterate err;
|
||||
Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]);
|
||||
tox_events_free(events);
|
||||
} else {
|
||||
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
||||
}
|
||||
autotoxes[i].clock += wait;
|
||||
}
|
||||
}
|
||||
@ -181,6 +192,7 @@ void kill_autotox(AutoTox *autotox)
|
||||
ck_assert(autotox->alive);
|
||||
fprintf(stderr, "Killing #%u\n", autotox->index);
|
||||
autotox->alive = false;
|
||||
tox_dispatch_free(autotox->dispatch);
|
||||
tox_kill(autotox->tox);
|
||||
}
|
||||
|
||||
@ -202,6 +214,11 @@ void reload(AutoTox *autotox)
|
||||
tox_options_set_savedata_data(options, autotox->save_state, autotox->save_size);
|
||||
autotox->tox = tox_new_log(options, nullptr, &autotox->index);
|
||||
ck_assert(autotox->tox != nullptr);
|
||||
autotox->dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(autotox->dispatch != nullptr);
|
||||
if (autotox->events) {
|
||||
tox_events_init(autotox->tox);
|
||||
}
|
||||
tox_options_free(options);
|
||||
|
||||
set_mono_time_callback(autotox);
|
||||
@ -212,6 +229,7 @@ static void initialise_autotox(struct Tox_Options *options, AutoTox *autotox, ui
|
||||
Run_Auto_Options *autotest_opts)
|
||||
{
|
||||
autotox->index = index;
|
||||
autotox->events = autotest_opts->events;
|
||||
|
||||
Tox_Err_New err = TOX_ERR_NEW_OK;
|
||||
|
||||
@ -259,6 +277,12 @@ static void initialise_autotox(struct Tox_Options *options, AutoTox *autotox, ui
|
||||
|
||||
set_mono_time_callback(autotox);
|
||||
|
||||
autotox->dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(autotox->dispatch != nullptr);
|
||||
if (autotox->events) {
|
||||
tox_events_init(autotox->tox);
|
||||
}
|
||||
|
||||
autotox->alive = true;
|
||||
autotox->save_state = nullptr;
|
||||
|
||||
@ -311,7 +335,7 @@ static void initialise_friend_graph(Graph_Type graph, uint32_t num_toxes, AutoTo
|
||||
}
|
||||
}
|
||||
|
||||
static void bootstrap_autotoxes(struct Tox_Options *options, uint32_t tox_count, const Run_Auto_Options *autotest_opts,
|
||||
static void bootstrap_autotoxes(const Tox_Options *options, uint32_t tox_count, const Run_Auto_Options *autotest_opts,
|
||||
AutoTox *autotoxes)
|
||||
{
|
||||
const bool udp_enabled = options != nullptr ? tox_options_get_udp_enabled(options) : true;
|
||||
@ -339,7 +363,9 @@ static void bootstrap_autotoxes(struct Tox_Options *options, uint32_t tox_count,
|
||||
}
|
||||
}
|
||||
|
||||
void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(AutoTox *autotoxes),
|
||||
typedef void autotox_test_cb(AutoTox *autotoxes);
|
||||
|
||||
void run_auto_test(struct Tox_Options *options, uint32_t tox_count, autotox_test_cb *test,
|
||||
uint32_t state_size, Run_Auto_Options *autotest_opts)
|
||||
{
|
||||
printf("initialising %u toxes\n", tox_count);
|
||||
@ -371,6 +397,7 @@ void run_auto_test(struct Tox_Options *options, uint32_t tox_count, void test(Au
|
||||
test(autotoxes);
|
||||
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
tox_dispatch_free(autotoxes[i].dispatch);
|
||||
tox_kill(autotoxes[i].tox);
|
||||
free(autotoxes[i].state);
|
||||
free(autotoxes[i].save_state);
|
||||
@ -417,7 +444,6 @@ void print_debug_log(Tox *m, Tox_Log_Level level, const char *file, uint32_t lin
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void print_debug_logger(void *context, Logger_Level level, const char *file, int line, const char *func, const char *message, void *userdata)
|
||||
{
|
||||
print_debug_log(nullptr, (Tox_Log_Level) level, file, (uint32_t) line, func, message, userdata);
|
||||
@ -455,4 +481,3 @@ Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_d
|
||||
{
|
||||
return tox_new_log_lan(options, err, log_user_data, false);
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,11 @@
|
||||
#include "../testing/misc_tools.h"
|
||||
#include "../toxcore/Messenger.h"
|
||||
#include "../toxcore/mono_time.h"
|
||||
#include "../toxcore/tox_dispatch.h"
|
||||
|
||||
typedef struct AutoTox {
|
||||
Tox *tox;
|
||||
Tox_Dispatch *dispatch;
|
||||
|
||||
uint32_t index;
|
||||
uint64_t clock;
|
||||
@ -17,6 +19,7 @@ typedef struct AutoTox {
|
||||
size_t save_size;
|
||||
uint8_t *save_state;
|
||||
bool alive;
|
||||
bool events;
|
||||
|
||||
void *state;
|
||||
} AutoTox;
|
||||
@ -42,6 +45,7 @@ typedef struct Run_Auto_Options {
|
||||
Graph_Type graph;
|
||||
void (*init_autotox)(AutoTox *autotox, uint32_t n);
|
||||
uint16_t tcp_port;
|
||||
bool events;
|
||||
} Run_Auto_Options;
|
||||
|
||||
Run_Auto_Options default_run_auto_options(void);
|
||||
@ -57,7 +61,7 @@ void print_debug_log(Tox *m, Tox_Log_Level level, const char *file, uint32_t lin
|
||||
|
||||
// Use this function when setting the log callback on a Logger object
|
||||
void print_debug_logger(void *context, Logger_Level level, const char *file, int line,
|
||||
const char *func, const char *message, void *userdata);
|
||||
const char *func, const char *message, void *userdata);
|
||||
|
||||
Tox *tox_new_log(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data);
|
||||
Tox *tox_new_log_lan(struct Tox_Options *options, Tox_Err_New *err, void *log_user_data, bool lan_discovery);
|
||||
|
@ -23,10 +23,11 @@ typedef struct State {
|
||||
} State;
|
||||
|
||||
static void handle_self_connection_status(
|
||||
Tox *tox, Tox_Connection connection_status, void *user_data)
|
||||
const Tox_Event_Self_Connection_Status *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
|
||||
const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event);
|
||||
if (connection_status != TOX_CONNECTION_NONE) {
|
||||
printf("tox #%u: is now connected\n", autotox->index);
|
||||
} else {
|
||||
@ -35,10 +36,13 @@ static void handle_self_connection_status(
|
||||
}
|
||||
|
||||
static void handle_friend_connection_status(
|
||||
Tox *tox, uint32_t friendnumber, Tox_Connection connection_status, void *user_data)
|
||||
const Tox_Event_Friend_Connection_Status *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
|
||||
const uint32_t friendnumber = tox_event_friend_connection_status_get_friend_number(event);
|
||||
const Tox_Connection connection_status = tox_event_friend_connection_status_get_connection_status(event);
|
||||
|
||||
if (connection_status != TOX_CONNECTION_NONE) {
|
||||
printf("tox #%u: is now connected to friend %u\n", autotox->index, friendnumber);
|
||||
} else {
|
||||
@ -70,28 +74,33 @@ static void audio_callback(void *tox, uint32_t groupnumber, uint32_t peernumber,
|
||||
}
|
||||
|
||||
static void handle_conference_invite(
|
||||
Tox *tox, uint32_t friendnumber, Tox_Conference_Type type,
|
||||
const uint8_t *data, size_t length, void *user_data)
|
||||
const Tox_Event_Conference_Invite *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
|
||||
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
|
||||
const Tox_Conference_Type type = tox_event_conference_invite_get_type(event);
|
||||
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
|
||||
const size_t length = tox_event_conference_invite_get_cookie_length(event);
|
||||
|
||||
ck_assert_msg(type == TOX_CONFERENCE_TYPE_AV, "tox #%u: wrong conference type: %d", autotox->index, type);
|
||||
|
||||
ck_assert_msg(toxav_join_av_groupchat(tox, friendnumber, data, length, audio_callback, user_data) == 0,
|
||||
ck_assert_msg(toxav_join_av_groupchat(autotox->tox, friend_number, cookie, length, audio_callback, user_data) == 0,
|
||||
"tox #%u: failed to join group", autotox->index);
|
||||
}
|
||||
|
||||
static void handle_conference_connected(
|
||||
Tox *tox, uint32_t conference_number, void *user_data)
|
||||
const Tox_Event_Conference_Connected *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) {
|
||||
if (state->invited_next || tox_self_get_friend_list_size(autotox->tox) <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(tox, 1, 0, &err);
|
||||
tox_conference_invite(autotox->tox, 1, 0, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index,
|
||||
err);
|
||||
printf("tox #%u: invited next friend\n", autotox->index);
|
||||
@ -99,7 +108,7 @@ static void handle_conference_connected(
|
||||
}
|
||||
|
||||
static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes,
|
||||
bool *disconnected)
|
||||
const bool *disconnected)
|
||||
{
|
||||
uint32_t num_disconnected = 0;
|
||||
|
||||
@ -138,7 +147,10 @@ static void disconnect_toxes(uint32_t tox_count, AutoTox *autotoxes,
|
||||
do {
|
||||
for (uint32_t i = 0; i < tox_count; ++i) {
|
||||
if (!disconnect_now[i]) {
|
||||
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
||||
Tox_Err_Events_Iterate err;
|
||||
Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err);
|
||||
tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]);
|
||||
tox_events_free(events);
|
||||
autotoxes[i].clock += 1000;
|
||||
}
|
||||
}
|
||||
@ -165,7 +177,7 @@ static bool all_connected_to_group(uint32_t tox_count, AutoTox *autotoxes)
|
||||
* returns a random index at which a list of booleans is false
|
||||
* (some such index is required to exist)
|
||||
*/
|
||||
static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length)
|
||||
static uint32_t random_false_index(const Random *rng, const bool *list, const uint32_t length)
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
@ -185,7 +197,7 @@ static bool all_got_audio(AutoTox *autotoxes, const bool *disabled)
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
State *state = (State *)autotoxes[i].state;
|
||||
const State *state = (const State *)autotoxes[i].state;
|
||||
|
||||
if (disabled[i] ^ (state->received_audio_num
|
||||
!= NUM_AV_GROUP_TOX - num_disabled - 1)) {
|
||||
@ -291,7 +303,7 @@ static void do_audio(AutoTox *autotoxes, uint32_t iterations)
|
||||
|
||||
static void run_conference_tests(AutoTox *autotoxes)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
bool disabled[NUM_AV_GROUP_TOX] = {0};
|
||||
|
||||
@ -402,10 +414,10 @@ static void test_groupav(AutoTox *autotoxes)
|
||||
const time_t test_start_time = time(nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_AV_GROUP_TOX; ++i) {
|
||||
tox_callback_self_connection_status(autotoxes[i].tox, &handle_self_connection_status);
|
||||
tox_callback_friend_connection_status(autotoxes[i].tox, &handle_friend_connection_status);
|
||||
tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite);
|
||||
tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected);
|
||||
tox_events_callback_self_connection_status(autotoxes[i].dispatch, handle_self_connection_status);
|
||||
tox_events_callback_friend_connection_status(autotoxes[i].dispatch, handle_friend_connection_status);
|
||||
tox_events_callback_conference_invite(autotoxes[i].dispatch, handle_conference_invite);
|
||||
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,
|
||||
@ -414,7 +426,6 @@ static void test_groupav(AutoTox *autotoxes)
|
||||
ck_assert_msg(tox_conference_invite(autotoxes[0].tox, 0, 0, nullptr) != 0, "failed to invite friend");
|
||||
((State *)autotoxes[0].state)->invited_next = true;
|
||||
|
||||
|
||||
printf("waiting for invitations to be made\n");
|
||||
uint32_t invited_count = 0;
|
||||
|
||||
|
@ -12,12 +12,16 @@ typedef struct State {
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void handle_conference_invite(
|
||||
Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
|
||||
const uint8_t *cookie, size_t length, void *user_data)
|
||||
const Tox_Event_Conference_Invite *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
|
||||
const Tox_Conference_Type type = tox_event_conference_invite_get_type(event);
|
||||
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
|
||||
const size_t length = tox_event_conference_invite_get_cookie_length(event);
|
||||
|
||||
fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n",
|
||||
autotox->index, friend_number, type, (unsigned)length);
|
||||
fprintf(stderr, "tox%u joining conference\n", autotox->index);
|
||||
@ -26,7 +30,7 @@ static void handle_conference_invite(
|
||||
|
||||
if (friend_number != -1) {
|
||||
Tox_Err_Conference_Join err;
|
||||
state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
|
||||
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
|
||||
"attempting to join the conference returned with an error: %d", err);
|
||||
fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference);
|
||||
@ -37,8 +41,8 @@ static void handle_conference_invite(
|
||||
static void conference_double_invite_test(AutoTox *autotoxes)
|
||||
{
|
||||
// Conference callbacks.
|
||||
tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite);
|
||||
tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite);
|
||||
tox_events_callback_conference_invite(autotoxes[0].dispatch, handle_conference_invite);
|
||||
tox_events_callback_conference_invite(autotoxes[1].dispatch, handle_conference_invite);
|
||||
|
||||
State *state[2];
|
||||
state[0] = (State *)autotoxes[0].state;
|
||||
|
@ -12,15 +12,18 @@ typedef struct State {
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void handle_conference_invite(
|
||||
Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
|
||||
const uint8_t *cookie, size_t length, void *user_data)
|
||||
const Tox_Event_Conference_Invite *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
|
||||
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) {
|
||||
Tox_Err_Conference_Join err;
|
||||
state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
|
||||
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
|
||||
"attempting to join the conference returned with an error: %d", err);
|
||||
fprintf(stderr, "#%u accepted invite to conference %u\n", autotox->index, state->conference);
|
||||
@ -28,7 +31,7 @@ static void handle_conference_invite(
|
||||
}
|
||||
|
||||
static void handle_conference_connected(
|
||||
Tox *tox, uint32_t conference_number, void *user_data)
|
||||
const Tox_Event_Conference_Connected *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
@ -37,7 +40,7 @@ static void handle_conference_connected(
|
||||
state->connected = true;
|
||||
}
|
||||
|
||||
static void wait_connected(AutoTox *autotoxes, AutoTox *autotox, uint32_t friendnumber)
|
||||
static void wait_connected(AutoTox *autotoxes, const AutoTox *autotox, uint32_t friendnumber)
|
||||
{
|
||||
do {
|
||||
iterate_all_wait(autotoxes, NUM_INVITE_MERGE_TOX, ITERATION_INTERVAL);
|
||||
@ -95,8 +98,8 @@ static void conference_invite_merge_test(AutoTox *autotoxes)
|
||||
// components will cause a split group to merge
|
||||
|
||||
for (int i = 0; i < NUM_INVITE_MERGE_TOX; i++) {
|
||||
tox_callback_conference_invite(autotoxes[i].tox, &handle_conference_invite);
|
||||
tox_callback_conference_connected(autotoxes[i].tox, &handle_conference_connected);
|
||||
tox_events_callback_conference_invite(autotoxes[i].dispatch, handle_conference_invite);
|
||||
tox_events_callback_conference_connected(autotoxes[i].dispatch, handle_conference_connected);
|
||||
}
|
||||
|
||||
State *state2 = (State *)autotoxes[2].state;
|
||||
|
@ -13,34 +13,39 @@ typedef struct State {
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void handle_conference_invite(
|
||||
Tox *tox, uint32_t friend_number, Tox_Conference_Type type,
|
||||
const uint8_t *cookie, size_t length, void *user_data)
|
||||
const Tox_Event_Conference_Invite *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
|
||||
const Tox_Conference_Type type = tox_event_conference_invite_get_type(event);
|
||||
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
|
||||
const size_t length = tox_event_conference_invite_get_cookie_length(event);
|
||||
|
||||
fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n",
|
||||
autotox->index, friend_number, type, (unsigned)length);
|
||||
fprintf(stderr, "tox%u joining conference\n", autotox->index);
|
||||
|
||||
Tox_Err_Conference_Join err;
|
||||
state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
|
||||
state->conference = tox_conference_join(autotox->tox, friend_number, cookie, length, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK,
|
||||
"attempting to join the conference returned with an error: %d", err);
|
||||
fprintf(stderr, "tox%u joined conference %u\n", autotox->index, state->conference);
|
||||
state->joined = true;
|
||||
}
|
||||
|
||||
static void handle_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data)
|
||||
static void handle_peer_list_changed(const Tox_Event_Conference_Peer_List_Changed *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t conference_number = tox_event_conference_peer_list_changed_get_conference_number(event);
|
||||
fprintf(stderr, "handle_peer_list_changed(#%u, %u, _)\n",
|
||||
autotox->index, conference_number);
|
||||
|
||||
Tox_Err_Conference_Peer_Query err;
|
||||
uint32_t const count = tox_conference_peer_count(tox, conference_number, &err);
|
||||
uint32_t const count = tox_conference_peer_count(autotox->tox, conference_number, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_PEER_QUERY_OK,
|
||||
"failed to get conference peer count: err = %d", err);
|
||||
printf("tox%u has %u peers\n", autotox->index, count);
|
||||
@ -75,10 +80,10 @@ static void rebuild_peer_list(Tox *tox)
|
||||
static void conference_peer_nick_test(AutoTox *autotoxes)
|
||||
{
|
||||
// Conference callbacks.
|
||||
tox_callback_conference_invite(autotoxes[0].tox, handle_conference_invite);
|
||||
tox_callback_conference_invite(autotoxes[1].tox, handle_conference_invite);
|
||||
tox_callback_conference_peer_list_changed(autotoxes[0].tox, handle_peer_list_changed);
|
||||
tox_callback_conference_peer_list_changed(autotoxes[1].tox, handle_peer_list_changed);
|
||||
tox_events_callback_conference_invite(autotoxes[0].dispatch, handle_conference_invite);
|
||||
tox_events_callback_conference_invite(autotoxes[1].dispatch, handle_conference_invite);
|
||||
tox_events_callback_conference_peer_list_changed(autotoxes[0].dispatch, handle_peer_list_changed);
|
||||
tox_events_callback_conference_peer_list_changed(autotoxes[1].dispatch, handle_peer_list_changed);
|
||||
|
||||
// Set the names of the toxes.
|
||||
tox_self_set_name(autotoxes[0].tox, (const uint8_t *)"test-tox-0", 10, nullptr);
|
||||
|
@ -3,11 +3,14 @@
|
||||
|
||||
#include "../testing/misc_tools.h"
|
||||
#include "../toxcore/tox.h"
|
||||
#include "../toxcore/tox_dispatch.h"
|
||||
#include "../toxcore/tox_events.h"
|
||||
#include "auto_test_support.h"
|
||||
#include "check_compat.h"
|
||||
|
||||
typedef struct State {
|
||||
uint32_t id;
|
||||
Tox *tox;
|
||||
bool self_online;
|
||||
bool friend_online;
|
||||
bool invited_next;
|
||||
@ -20,46 +23,57 @@ typedef struct State {
|
||||
uint32_t peers;
|
||||
} State;
|
||||
|
||||
static void handle_self_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data)
|
||||
static void handle_self_connection_status(const Tox_Event_Self_Connection_Status *event, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
|
||||
const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event);
|
||||
fprintf(stderr, "self_connection_status(#%u, %d, _)\n", state->id, connection_status);
|
||||
state->self_online = connection_status != TOX_CONNECTION_NONE;
|
||||
}
|
||||
|
||||
static void handle_friend_connection_status(Tox *tox, uint32_t friend_number, Tox_Connection connection_status,
|
||||
static void handle_friend_connection_status(const Tox_Event_Friend_Connection_Status *event,
|
||||
void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
|
||||
const uint32_t friend_number = tox_event_friend_connection_status_get_friend_number(event);
|
||||
const Tox_Connection connection_status = tox_event_friend_connection_status_get_connection_status(event);
|
||||
fprintf(stderr, "handle_friend_connection_status(#%u, %u, %d, _)\n", state->id, friend_number, connection_status);
|
||||
state->friend_online = connection_status != TOX_CONNECTION_NONE;
|
||||
}
|
||||
|
||||
static void handle_conference_invite(Tox *tox, uint32_t friend_number, Tox_Conference_Type type, const uint8_t *cookie,
|
||||
size_t length, void *user_data)
|
||||
static void handle_conference_invite(const Tox_Event_Conference_Invite *event, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
|
||||
const uint32_t friend_number = tox_event_conference_invite_get_friend_number(event);
|
||||
const Tox_Conference_Type type = tox_event_conference_invite_get_type(event);
|
||||
const uint8_t *cookie = tox_event_conference_invite_get_cookie(event);
|
||||
const size_t length = tox_event_conference_invite_get_cookie_length(event);
|
||||
fprintf(stderr, "handle_conference_invite(#%u, %u, %d, uint8_t[%u], _)\n",
|
||||
state->id, friend_number, type, (unsigned)length);
|
||||
fprintf(stderr, "tox%u joining conference\n", state->id);
|
||||
|
||||
{
|
||||
Tox_Err_Conference_Join err;
|
||||
state->conference = tox_conference_join(tox, friend_number, cookie, length, &err);
|
||||
state->conference = tox_conference_join(state->tox, friend_number, cookie, length, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "failed to join a conference: err = %d", err);
|
||||
fprintf(stderr, "tox%u Joined conference %u\n", state->id, state->conference);
|
||||
state->joined = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_conference_message(Tox *tox, uint32_t conference_number, uint32_t peer_number,
|
||||
Tox_Message_Type type, const uint8_t *message, size_t length, void *user_data)
|
||||
static void handle_conference_message(const Tox_Event_Conference_Message *event, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
|
||||
const uint32_t conference_number = tox_event_conference_message_get_conference_number(event);
|
||||
const uint32_t peer_number = tox_event_conference_message_get_peer_number(event);
|
||||
const Tox_Message_Type type = tox_event_conference_message_get_type(event);
|
||||
const uint8_t *message = tox_event_conference_message_get_message(event);
|
||||
const size_t length = tox_event_conference_message_get_message_length(event);
|
||||
|
||||
fprintf(stderr, "handle_conference_message(#%u, %u, %u, %d, uint8_t[%u], _)\n",
|
||||
state->id, conference_number, peer_number, type, (unsigned)length);
|
||||
|
||||
@ -67,15 +81,16 @@ static void handle_conference_message(Tox *tox, uint32_t conference_number, uint
|
||||
state->received = true;
|
||||
}
|
||||
|
||||
static void handle_conference_peer_list_changed(Tox *tox, uint32_t conference_number, void *user_data)
|
||||
static void handle_conference_peer_list_changed(const Tox_Event_Conference_Peer_List_Changed *event, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
|
||||
const uint32_t conference_number = tox_event_conference_peer_list_changed_get_conference_number(event);
|
||||
fprintf(stderr, "handle_conference_peer_list_changed(#%u, %u, _)\n",
|
||||
state->id, conference_number);
|
||||
|
||||
Tox_Err_Conference_Peer_Query err;
|
||||
uint32_t count = tox_conference_peer_count(tox, conference_number, &err);
|
||||
uint32_t count = tox_conference_peer_count(state->tox, conference_number, &err);
|
||||
|
||||
if (err != TOX_ERR_CONFERENCE_PEER_QUERY_OK) {
|
||||
fprintf(stderr, "ERROR: %d\n", err);
|
||||
@ -86,14 +101,14 @@ static void handle_conference_peer_list_changed(Tox *tox, uint32_t conference_nu
|
||||
state->peers = count;
|
||||
}
|
||||
|
||||
static void handle_conference_connected(Tox *tox, uint32_t conference_number, void *user_data)
|
||||
static void handle_conference_connected(const Tox_Event_Conference_Connected *event, void *user_data)
|
||||
{
|
||||
State *state = (State *)user_data;
|
||||
|
||||
// We're tox2, so now we invite tox3.
|
||||
if (state->id == 2 && !state->invited_next) {
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(tox, 1, state->conference, &err);
|
||||
tox_conference_invite(state->tox, 1, state->conference, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox2 failed to invite tox3: err = %d", err);
|
||||
|
||||
state->invited_next = true;
|
||||
@ -101,6 +116,27 @@ static void handle_conference_connected(Tox *tox, uint32_t conference_number, vo
|
||||
}
|
||||
}
|
||||
|
||||
static void iterate_one(
|
||||
Tox *tox, State *state, const Tox_Dispatch *dispatch)
|
||||
{
|
||||
Tox_Err_Events_Iterate err;
|
||||
Tox_Events *events = tox_events_iterate(tox, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch, events, state);
|
||||
tox_events_free(events);
|
||||
}
|
||||
|
||||
static void iterate3_wait(
|
||||
State *state1, State *state2, State *state3,
|
||||
const Tox_Dispatch *dispatch, int interval)
|
||||
{
|
||||
iterate_one(state1->tox, state1, dispatch);
|
||||
iterate_one(state2->tox, state2, dispatch);
|
||||
iterate_one(state3->tox, state3, dispatch);
|
||||
|
||||
c_sleep(interval);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
@ -110,64 +146,51 @@ int main(void)
|
||||
State state3 = {3};
|
||||
|
||||
// Create toxes.
|
||||
Tox *tox1 = tox_new_log(nullptr, nullptr, &state1.id);
|
||||
Tox *tox2 = tox_new_log(nullptr, nullptr, &state2.id);
|
||||
Tox *tox3 = tox_new_log(nullptr, nullptr, &state3.id);
|
||||
state1.tox = tox_new_log(nullptr, nullptr, &state1.id);
|
||||
state2.tox = tox_new_log(nullptr, nullptr, &state2.id);
|
||||
state3.tox = tox_new_log(nullptr, nullptr, &state3.id);
|
||||
|
||||
tox_events_init(state1.tox);
|
||||
tox_events_init(state2.tox);
|
||||
tox_events_init(state3.tox);
|
||||
|
||||
// tox1 <-> tox2, tox2 <-> tox3
|
||||
uint8_t key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_public_key(tox2, key);
|
||||
tox_friend_add_norequest(tox1, key, nullptr); // tox1 -> tox2
|
||||
tox_self_get_public_key(tox1, key);
|
||||
tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox1
|
||||
tox_self_get_public_key(tox3, key);
|
||||
tox_friend_add_norequest(tox2, key, nullptr); // tox2 -> tox3
|
||||
tox_self_get_public_key(tox2, key);
|
||||
tox_friend_add_norequest(tox3, key, nullptr); // tox3 -> tox2
|
||||
tox_self_get_public_key(state2.tox, key);
|
||||
tox_friend_add_norequest(state1.tox, key, nullptr); // tox1 -> tox2
|
||||
tox_self_get_public_key(state1.tox, key);
|
||||
tox_friend_add_norequest(state2.tox, key, nullptr); // tox2 -> tox1
|
||||
tox_self_get_public_key(state3.tox, key);
|
||||
tox_friend_add_norequest(state2.tox, key, nullptr); // tox2 -> tox3
|
||||
tox_self_get_public_key(state2.tox, key);
|
||||
tox_friend_add_norequest(state3.tox, key, nullptr); // tox3 -> tox2
|
||||
|
||||
printf("bootstrapping tox2 and tox3 off tox1\n");
|
||||
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_dht_id(tox1, dht_key);
|
||||
const uint16_t dht_port = tox_self_get_udp_port(tox1, nullptr);
|
||||
tox_self_get_dht_id(state1.tox, dht_key);
|
||||
const uint16_t dht_port = tox_self_get_udp_port(state1.tox, nullptr);
|
||||
|
||||
tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr);
|
||||
tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr);
|
||||
tox_bootstrap(state2.tox, "localhost", dht_port, dht_key, nullptr);
|
||||
tox_bootstrap(state3.tox, "localhost", dht_port, dht_key, nullptr);
|
||||
|
||||
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch != nullptr);
|
||||
|
||||
// Connection callbacks.
|
||||
tox_callback_self_connection_status(tox1, handle_self_connection_status);
|
||||
tox_callback_self_connection_status(tox2, handle_self_connection_status);
|
||||
tox_callback_self_connection_status(tox3, handle_self_connection_status);
|
||||
|
||||
tox_callback_friend_connection_status(tox1, handle_friend_connection_status);
|
||||
tox_callback_friend_connection_status(tox2, handle_friend_connection_status);
|
||||
tox_callback_friend_connection_status(tox3, handle_friend_connection_status);
|
||||
tox_events_callback_self_connection_status(dispatch, handle_self_connection_status);
|
||||
tox_events_callback_friend_connection_status(dispatch, handle_friend_connection_status);
|
||||
|
||||
// Conference callbacks.
|
||||
tox_callback_conference_invite(tox1, handle_conference_invite);
|
||||
tox_callback_conference_invite(tox2, handle_conference_invite);
|
||||
tox_callback_conference_invite(tox3, handle_conference_invite);
|
||||
|
||||
tox_callback_conference_connected(tox1, handle_conference_connected);
|
||||
tox_callback_conference_connected(tox2, handle_conference_connected);
|
||||
tox_callback_conference_connected(tox3, handle_conference_connected);
|
||||
|
||||
tox_callback_conference_message(tox1, handle_conference_message);
|
||||
tox_callback_conference_message(tox2, handle_conference_message);
|
||||
tox_callback_conference_message(tox3, handle_conference_message);
|
||||
|
||||
tox_callback_conference_peer_list_changed(tox1, handle_conference_peer_list_changed);
|
||||
tox_callback_conference_peer_list_changed(tox2, handle_conference_peer_list_changed);
|
||||
tox_callback_conference_peer_list_changed(tox3, handle_conference_peer_list_changed);
|
||||
tox_events_callback_conference_invite(dispatch, handle_conference_invite);
|
||||
tox_events_callback_conference_connected(dispatch, handle_conference_connected);
|
||||
tox_events_callback_conference_message(dispatch, handle_conference_message);
|
||||
tox_events_callback_conference_peer_list_changed(dispatch, handle_conference_peer_list_changed);
|
||||
|
||||
// Wait for self connection.
|
||||
fprintf(stderr, "Waiting for toxes to come online\n");
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, &state1);
|
||||
tox_iterate(tox2, &state2);
|
||||
tox_iterate(tox3, &state3);
|
||||
|
||||
c_sleep(100);
|
||||
iterate3_wait(&state1, &state2, &state3, dispatch, 100);
|
||||
} while (!state1.self_online || !state2.self_online || !state3.self_online);
|
||||
|
||||
fprintf(stderr, "Toxes are online\n");
|
||||
@ -176,11 +199,7 @@ int main(void)
|
||||
fprintf(stderr, "Waiting for friends to connect\n");
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, &state1);
|
||||
tox_iterate(tox2, &state2);
|
||||
tox_iterate(tox3, &state3);
|
||||
|
||||
c_sleep(100);
|
||||
iterate3_wait(&state1, &state2, &state3, dispatch, 100);
|
||||
} while (!state1.friend_online || !state2.friend_online || !state3.friend_online);
|
||||
|
||||
fprintf(stderr, "Friends are connected\n");
|
||||
@ -188,7 +207,7 @@ int main(void)
|
||||
{
|
||||
// Create new conference, tox1 is the founder.
|
||||
Tox_Err_Conference_New err;
|
||||
state1.conference = tox_conference_new(tox1, &err);
|
||||
state1.conference = tox_conference_new(state1.tox, &err);
|
||||
state1.joined = true;
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_NEW_OK, "failed to create a conference: err = %d", err);
|
||||
fprintf(stderr, "Created conference: id = %u\n", state1.conference);
|
||||
@ -197,7 +216,7 @@ int main(void)
|
||||
{
|
||||
// Invite friend.
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(tox1, 0, state1.conference, &err);
|
||||
tox_conference_invite(state1.tox, 0, state1.conference, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "failed to invite a friend: err = %d", err);
|
||||
state1.invited_next = true;
|
||||
fprintf(stderr, "tox1 invited tox2\n");
|
||||
@ -206,11 +225,7 @@ int main(void)
|
||||
fprintf(stderr, "Waiting for invitation to arrive\n");
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, &state1);
|
||||
tox_iterate(tox2, &state2);
|
||||
tox_iterate(tox3, &state3);
|
||||
|
||||
c_sleep(100);
|
||||
iterate3_wait(&state1, &state2, &state3, dispatch, 100);
|
||||
} while (!state1.joined || !state2.joined || !state3.joined);
|
||||
|
||||
fprintf(stderr, "Invitations accepted\n");
|
||||
@ -218,11 +233,7 @@ int main(void)
|
||||
fprintf(stderr, "Waiting for peers to come online\n");
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, &state1);
|
||||
tox_iterate(tox2, &state2);
|
||||
tox_iterate(tox3, &state3);
|
||||
|
||||
c_sleep(100);
|
||||
iterate3_wait(&state1, &state2, &state3, dispatch, 100);
|
||||
} while (state1.peers == 0 || state2.peers == 0 || state3.peers == 0);
|
||||
|
||||
fprintf(stderr, "All peers are online\n");
|
||||
@ -230,7 +241,7 @@ int main(void)
|
||||
{
|
||||
fprintf(stderr, "tox1 sends a message to the group: \"hello!\"\n");
|
||||
Tox_Err_Conference_Send_Message err;
|
||||
tox_conference_send_message(tox1, state1.conference, TOX_MESSAGE_TYPE_NORMAL,
|
||||
tox_conference_send_message(state1.tox, state1.conference, TOX_MESSAGE_TYPE_NORMAL,
|
||||
(const uint8_t *)"hello!", 7, &err);
|
||||
|
||||
if (err != TOX_ERR_CONFERENCE_SEND_MESSAGE_OK) {
|
||||
@ -242,18 +253,16 @@ int main(void)
|
||||
fprintf(stderr, "Waiting for messages to arrive\n");
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, &state1);
|
||||
tox_iterate(tox2, &state2);
|
||||
tox_iterate(tox3, &state3);
|
||||
|
||||
iterate3_wait(&state1, &state2, &state3, dispatch, 100);
|
||||
c_sleep(100);
|
||||
} while (!state2.received || !state3.received);
|
||||
|
||||
fprintf(stderr, "Messages received. Test complete.\n");
|
||||
|
||||
tox_kill(tox3);
|
||||
tox_kill(tox2);
|
||||
tox_kill(tox1);
|
||||
tox_dispatch_free(dispatch);
|
||||
tox_kill(state3.tox);
|
||||
tox_kill(state2.tox);
|
||||
tox_kill(state1.tox);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -56,13 +56,13 @@ static void handle_conference_invite(
|
||||
ck_assert_msg(type == TOX_CONFERENCE_TYPE_TEXT, "tox #%u: wrong conference type: %d", autotox->index, type);
|
||||
|
||||
Tox_Err_Conference_Join err;
|
||||
uint32_t g_num = tox_conference_join(tox, friendnumber, data, length, &err);
|
||||
uint32_t g_num = tox_conference_join(autotox->tox, friendnumber, data, length, &err);
|
||||
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_JOIN_OK, "tox #%u: error joining group: %d", autotox->index, err);
|
||||
ck_assert_msg(g_num == 0, "tox #%u: group number was not 0", autotox->index);
|
||||
|
||||
// Try joining again. We should only be allowed to join once.
|
||||
tox_conference_join(tox, friendnumber, data, length, &err);
|
||||
tox_conference_join(autotox->tox, friendnumber, data, length, &err);
|
||||
ck_assert_msg(err != TOX_ERR_CONFERENCE_JOIN_OK,
|
||||
"tox #%u: joining groupchat twice should be impossible.", autotox->index);
|
||||
}
|
||||
@ -73,12 +73,12 @@ static void handle_conference_connected(
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
if (state->invited_next || tox_self_get_friend_list_size(tox) <= 1) {
|
||||
if (state->invited_next || tox_self_get_friend_list_size(autotox->tox) <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Tox_Err_Conference_Invite err;
|
||||
tox_conference_invite(tox, 1, 0, &err);
|
||||
tox_conference_invite(autotox->tox, 1, 0, &err);
|
||||
ck_assert_msg(err == TOX_ERR_CONFERENCE_INVITE_OK, "tox #%u failed to invite next friend: err = %d", autotox->index,
|
||||
err);
|
||||
printf("tox #%u: invited next friend\n", autotox->index);
|
||||
@ -97,7 +97,7 @@ static void handle_conference_message(
|
||||
}
|
||||
|
||||
static bool toxes_are_disconnected_from_group(uint32_t tox_count, AutoTox *autotoxes,
|
||||
bool *disconnected)
|
||||
const bool *disconnected)
|
||||
{
|
||||
uint32_t num_disconnected = 0;
|
||||
|
||||
@ -174,12 +174,11 @@ static bool names_propagated(uint32_t tox_count, AutoTox *autotoxes)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns a random index at which a list of booleans is false
|
||||
* (some such index is required to exist)
|
||||
*/
|
||||
static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t length)
|
||||
static uint32_t random_false_index(const Random *rng, const bool *list, const uint32_t length)
|
||||
{
|
||||
uint32_t index;
|
||||
|
||||
@ -192,7 +191,7 @@ static uint32_t random_false_index(const Random *rng, bool *list, const uint32_t
|
||||
|
||||
static void run_conference_tests(AutoTox *autotoxes)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
/* disabling name change propagation check for now, as it occasionally
|
||||
* fails due to disconnections too short to trigger freezing */
|
||||
@ -357,7 +356,6 @@ static void test_many_group(AutoTox *autotoxes)
|
||||
nullptr) != 0,
|
||||
"failed to set group title");
|
||||
|
||||
|
||||
printf("waiting for invitations to be made\n");
|
||||
uint32_t invited_count = 0;
|
||||
|
||||
@ -435,6 +433,7 @@ int main(void)
|
||||
|
||||
Run_Auto_Options options = default_run_auto_options();
|
||||
options.graph = GRAPH_LINEAR;
|
||||
options.events = false;
|
||||
|
||||
run_auto_test(nullptr, NUM_GROUP_TOX, test_many_group, sizeof(State), &options);
|
||||
return 0;
|
||||
|
@ -125,7 +125,7 @@ static void test_fast_known(void)
|
||||
|
||||
static void test_endtoend(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
// Test 100 random messages and keypairs
|
||||
@ -192,7 +192,7 @@ static void test_endtoend(void)
|
||||
|
||||
static void test_large_data(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
uint8_t k[CRYPTO_SHARED_KEY_SIZE];
|
||||
uint8_t n[CRYPTO_NONCE_SIZE];
|
||||
@ -236,7 +236,7 @@ static void test_large_data(void)
|
||||
|
||||
static void test_large_data_symmetric(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
uint8_t k[CRYPTO_SYMMETRIC_KEY_SIZE];
|
||||
|
||||
@ -271,10 +271,10 @@ static void test_large_data_symmetric(void)
|
||||
|
||||
static void test_very_large_data(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
uint8_t nonce[CRYPTO_NONCE_SIZE] = {0};
|
||||
const uint8_t nonce[CRYPTO_NONCE_SIZE] = {0};
|
||||
uint8_t pk[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
uint8_t sk[CRYPTO_SECRET_KEY_SIZE];
|
||||
crypto_new_keypair(rng, pk, sk);
|
||||
@ -316,7 +316,7 @@ static void increment_nonce_number_cmp(uint8_t *nonce, uint32_t num)
|
||||
|
||||
static void test_increment_nonce(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
uint8_t n[CRYPTO_NONCE_SIZE];
|
||||
|
Binary file not shown.
BIN
auto_tests/data/save.tox.little
Normal file
BIN
auto_tests/data/save.tox.little
Normal file
Binary file not shown.
@ -72,12 +72,16 @@ static bool all_nodes_crawled(const AutoTox *autotoxes, uint32_t num_toxes, uint
|
||||
return true;
|
||||
}
|
||||
|
||||
static void getnodes_response_cb(Tox *tox, const uint8_t *public_key, const char *ip, uint16_t port, void *user_data)
|
||||
static void getnodes_response_cb(const Tox_Event_Dht_Get_Nodes_Response *event, void *user_data)
|
||||
{
|
||||
ck_assert(user_data != nullptr);
|
||||
|
||||
AutoTox *autotoxes = (AutoTox *)user_data;
|
||||
State *state = (State *)autotoxes->state;
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint8_t *public_key = tox_event_dht_get_nodes_response_get_public_key(event);
|
||||
const char *ip = (const char *)tox_event_dht_get_nodes_response_get_ip(event);
|
||||
const uint16_t port = tox_event_dht_get_nodes_response_get_port(event);
|
||||
|
||||
if (node_crawled(state->nodes, state->num_nodes, public_key)) {
|
||||
return;
|
||||
@ -97,7 +101,7 @@ static void getnodes_response_cb(Tox *tox, const uint8_t *public_key, const char
|
||||
|
||||
// ask new node to give us their close nodes to every public key
|
||||
for (size_t i = 0; i < NUM_TOXES; ++i) {
|
||||
tox_dht_get_nodes(tox, public_key, ip, port, state->public_key_list[i], nullptr);
|
||||
tox_dht_get_nodes(autotox->tox, public_key, ip, port, state->public_key_list[i], nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,13 +125,12 @@ static void test_dht_getnodes(AutoTox *autotoxes)
|
||||
ck_assert(public_key_list[i] != nullptr);
|
||||
|
||||
tox_self_get_dht_id(autotoxes[i].tox, public_key_list[i]);
|
||||
tox_callback_dht_get_nodes_response(autotoxes[i].tox, getnodes_response_cb);
|
||||
tox_events_callback_dht_get_nodes_response(autotoxes[i].dispatch, getnodes_response_cb);
|
||||
|
||||
printf("Peer %zu dht closenode count total/announce-capable: %d/%d\n",
|
||||
i,
|
||||
tox_dht_get_num_closelist(autotoxes[i].tox),
|
||||
tox_dht_get_num_closelist_announce_capable(autotoxes[i].tox)
|
||||
);
|
||||
i,
|
||||
tox_dht_get_num_closelist(autotoxes[i].tox),
|
||||
tox_dht_get_num_closelist_announce_capable(autotoxes[i].tox));
|
||||
}
|
||||
|
||||
while (!all_nodes_crawled(autotoxes, NUM_TOXES, public_key_list)) {
|
||||
|
@ -168,7 +168,7 @@ static void test_keys(void)
|
||||
ck_assert(encrypted2a != nullptr);
|
||||
uint8_t *in_plaintext2a = (uint8_t *)malloc(plaintext_length2a);
|
||||
ck_assert(in_plaintext2a != nullptr);
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
random_bytes(rng, in_plaintext2a, plaintext_length2a);
|
||||
ret = tox_pass_encrypt(in_plaintext2a, plaintext_length2a, key_char, 12, encrypted2a, &encerr);
|
||||
@ -184,7 +184,6 @@ static void test_keys(void)
|
||||
free(in_plaintext2a);
|
||||
free(out_plaintext2a);
|
||||
|
||||
|
||||
uint8_t encrypted2[44 + TOX_PASS_ENCRYPTION_EXTRA_LENGTH];
|
||||
ret = tox_pass_encrypt(string, 44, key_char, 12, encrypted2, &encerr);
|
||||
ck_assert_msg(ret, "generic failure 3: %d", encerr);
|
||||
|
@ -53,7 +53,7 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num
|
||||
|
||||
ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id");
|
||||
|
||||
uint8_t empty[TOX_FILE_ID_LENGTH] = {0};
|
||||
const uint8_t empty[TOX_FILE_ID_LENGTH] = {0};
|
||||
|
||||
ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id");
|
||||
|
||||
@ -126,7 +126,6 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi
|
||||
Tox_Err_File_Send_Chunk error;
|
||||
tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error);
|
||||
|
||||
|
||||
ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK,
|
||||
"could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length);
|
||||
|
||||
@ -134,7 +133,6 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi
|
||||
sending_pos += length;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t num;
|
||||
static bool file_recv;
|
||||
static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data,
|
||||
@ -209,7 +207,6 @@ static void file_transfer_test(void)
|
||||
file_accepted = file_size = sendf_ok = size_recv = 0;
|
||||
file_recv = 0;
|
||||
max_sending = UINT64_MAX;
|
||||
uint64_t totalf_size = 100 * 1024 * 1024;
|
||||
|
||||
printf("Starting file streaming transfer test.\n");
|
||||
|
||||
@ -224,10 +221,10 @@ static void file_transfer_test(void)
|
||||
tox_callback_file_chunk_request(tox2, tox_file_chunk_request);
|
||||
tox_callback_file_recv_control(tox3, file_print_control);
|
||||
tox_callback_file_recv(tox3, tox_file_receive);
|
||||
totalf_size = UINT64_MAX;
|
||||
const uint64_t totalf_size = UINT64_MAX;
|
||||
Tox_File_Number fnum = tox_file_send(
|
||||
tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr,
|
||||
(const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr);
|
||||
tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr,
|
||||
(const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr);
|
||||
ck_assert_msg(fnum != UINT32_MAX, "tox_new_file_sender fail");
|
||||
|
||||
Tox_Err_File_Get gfierr;
|
||||
|
@ -26,10 +26,16 @@
|
||||
#define TOX_LOCALHOST "127.0.0.1"
|
||||
#endif
|
||||
|
||||
static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
|
||||
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata)
|
||||
{
|
||||
Tox *tox = (Tox *)userdata;
|
||||
|
||||
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
|
||||
const uint8_t *data = tox_event_friend_request_get_message(event);
|
||||
const size_t length = tox_event_friend_request_get_message_length(event);
|
||||
|
||||
if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
|
||||
tox_friend_add_norequest(m, public_key, nullptr);
|
||||
tox_friend_add_norequest(tox, public_key, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,9 +45,17 @@ static uint64_t sending_pos;
|
||||
static uint8_t file_cmp_id[TOX_FILE_ID_LENGTH];
|
||||
static uint32_t file_accepted;
|
||||
static uint64_t file_size;
|
||||
static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_number, uint32_t kind, uint64_t filesize,
|
||||
const uint8_t *filename, size_t filename_length, void *userdata)
|
||||
static void tox_file_receive(const Tox_Event_File_Recv *event, void *userdata)
|
||||
{
|
||||
Tox *state_tox = (Tox *)userdata;
|
||||
|
||||
const uint32_t friend_number = tox_event_file_recv_get_friend_number(event);
|
||||
const uint32_t file_number = tox_event_file_recv_get_file_number(event);
|
||||
const uint32_t kind = tox_event_file_recv_get_kind(event);
|
||||
const uint64_t filesize = tox_event_file_recv_get_file_size(event);
|
||||
const uint8_t *filename = tox_event_file_recv_get_filename(event);
|
||||
const size_t filename_length = tox_event_file_recv_get_filename_length(event);
|
||||
|
||||
ck_assert_msg(kind == TOX_FILE_KIND_DATA, "bad kind");
|
||||
|
||||
ck_assert_msg(filename_length == sizeof("Gentoo.exe")
|
||||
@ -49,11 +63,11 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num
|
||||
|
||||
uint8_t file_id[TOX_FILE_ID_LENGTH];
|
||||
|
||||
ck_assert_msg(tox_file_get_file_id(tox, friend_number, file_number, file_id, nullptr), "tox_file_get_file_id error");
|
||||
ck_assert_msg(tox_file_get_file_id(state_tox, friend_number, file_number, file_id, nullptr), "tox_file_get_file_id error");
|
||||
|
||||
ck_assert_msg(memcmp(file_id, file_cmp_id, TOX_FILE_ID_LENGTH) == 0, "bad file_id");
|
||||
|
||||
uint8_t empty[TOX_FILE_ID_LENGTH] = {0};
|
||||
const uint8_t empty[TOX_FILE_ID_LENGTH] = {0};
|
||||
|
||||
ck_assert_msg(memcmp(empty, file_cmp_id, TOX_FILE_ID_LENGTH) != 0, "empty file_id");
|
||||
|
||||
@ -64,7 +78,7 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num
|
||||
|
||||
Tox_Err_File_Seek err_s;
|
||||
|
||||
ck_assert_msg(tox_file_seek(tox, friend_number, file_number, 1337, &err_s), "tox_file_seek error");
|
||||
ck_assert_msg(tox_file_seek(state_tox, friend_number, file_number, 1337, &err_s), "tox_file_seek error");
|
||||
|
||||
ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_OK, "tox_file_seek wrong error");
|
||||
|
||||
@ -74,21 +88,24 @@ static void tox_file_receive(Tox *tox, uint32_t friend_number, uint32_t file_num
|
||||
|
||||
Tox_Err_File_Control error;
|
||||
|
||||
ck_assert_msg(tox_file_control(tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, &error),
|
||||
ck_assert_msg(tox_file_control(state_tox, friend_number, file_number, TOX_FILE_CONTROL_RESUME, &error),
|
||||
"tox_file_control failed. %i", error);
|
||||
++file_accepted;
|
||||
|
||||
Tox_Err_File_Seek err_s;
|
||||
|
||||
ck_assert_msg(!tox_file_seek(tox, friend_number, file_number, 1234, &err_s), "tox_file_seek no error");
|
||||
ck_assert_msg(!tox_file_seek(state_tox, friend_number, file_number, 1234, &err_s), "tox_file_seek no error");
|
||||
|
||||
ck_assert_msg(err_s == TOX_ERR_FILE_SEEK_DENIED, "tox_file_seek wrong error");
|
||||
}
|
||||
|
||||
static uint32_t sendf_ok;
|
||||
static void file_print_control(Tox *tox, uint32_t friend_number, uint32_t file_number, Tox_File_Control control,
|
||||
static void file_print_control(const Tox_Event_File_Recv_Control *event,
|
||||
void *userdata)
|
||||
{
|
||||
const uint32_t file_number = tox_event_file_recv_control_get_file_number(event);
|
||||
const Tox_File_Control control = tox_event_file_recv_control_get_control(event);
|
||||
|
||||
/* First send file num is 0.*/
|
||||
if (file_number == 0 && control == TOX_FILE_CONTROL_RESUME) {
|
||||
sendf_ok = 1;
|
||||
@ -99,12 +116,18 @@ static uint64_t max_sending;
|
||||
static bool m_send_reached;
|
||||
static uint8_t sending_num;
|
||||
static bool file_sending_done;
|
||||
static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t file_number, uint64_t position,
|
||||
size_t length, void *user_data)
|
||||
static void tox_file_chunk_request(const Tox_Event_File_Chunk_Request *event, void *user_data)
|
||||
{
|
||||
Tox *state_tox = (Tox *)user_data;
|
||||
|
||||
const uint32_t friend_number = tox_event_file_chunk_request_get_friend_number(event);
|
||||
const uint32_t file_number = tox_event_file_chunk_request_get_file_number(event);
|
||||
const uint64_t position = tox_event_file_chunk_request_get_position(event);
|
||||
size_t length = tox_event_file_chunk_request_get_length(event);
|
||||
|
||||
ck_assert_msg(sendf_ok, "didn't get resume control");
|
||||
|
||||
ck_assert_msg(sending_pos == position, "bad position %lu", (unsigned long)position);
|
||||
ck_assert_msg(sending_pos == position, "bad position %lu (should be %lu)", (unsigned long)position, (unsigned long)sending_pos);
|
||||
|
||||
if (length == 0) {
|
||||
ck_assert_msg(!file_sending_done, "file sending already done");
|
||||
@ -124,8 +147,7 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi
|
||||
memset(f_data, sending_num, length);
|
||||
|
||||
Tox_Err_File_Send_Chunk error;
|
||||
tox_file_send_chunk(tox, friend_number, file_number, position, f_data, length, &error);
|
||||
|
||||
tox_file_send_chunk(state_tox, friend_number, file_number, position, f_data, length, &error);
|
||||
|
||||
ck_assert_msg(error == TOX_ERR_FILE_SEND_CHUNK_OK,
|
||||
"could not send chunk, error num=%d pos=%d len=%d", (int)error, (int)position, (int)length);
|
||||
@ -134,12 +156,14 @@ static void tox_file_chunk_request(Tox *tox, uint32_t friend_number, uint32_t fi
|
||||
sending_pos += length;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t num;
|
||||
static bool file_recv;
|
||||
static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t position, const uint8_t *data,
|
||||
size_t length, void *user_data)
|
||||
static void write_file(const Tox_Event_File_Recv_Chunk *event, void *user_data)
|
||||
{
|
||||
const uint64_t position = tox_event_file_recv_chunk_get_position(event);
|
||||
const uint8_t *data = tox_event_file_recv_chunk_get_data(event);
|
||||
const size_t length = tox_event_file_recv_chunk_get_data_length(event);
|
||||
|
||||
ck_assert_msg(size_recv == position, "bad position");
|
||||
|
||||
if (length == 0) {
|
||||
@ -156,6 +180,17 @@ static void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uin
|
||||
size_recv += length;
|
||||
}
|
||||
|
||||
static void iterate_and_dispatch(const Tox_Dispatch *dispatch, Tox *tox)
|
||||
{
|
||||
Tox_Err_Events_Iterate err;
|
||||
Tox_Events *events;
|
||||
|
||||
events = tox_events_iterate(tox, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch, events, tox);
|
||||
tox_events_free(events);
|
||||
}
|
||||
|
||||
static void file_transfer_test(void)
|
||||
{
|
||||
printf("Starting test: few_clients\n");
|
||||
@ -171,7 +206,19 @@ static void file_transfer_test(void)
|
||||
|
||||
ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances");
|
||||
|
||||
tox_callback_friend_request(tox2, accept_friend_request);
|
||||
tox_events_init(tox1);
|
||||
tox_events_init(tox2);
|
||||
tox_events_init(tox3);
|
||||
|
||||
Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch1 != nullptr);
|
||||
Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch2 != nullptr);
|
||||
Tox_Dispatch *dispatch3 = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch3 != nullptr);
|
||||
|
||||
tox_events_callback_friend_request(dispatch2, accept_friend_request);
|
||||
|
||||
uint8_t address[TOX_ADDRESS_SIZE];
|
||||
tox_self_get_address(tox2, address);
|
||||
uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr);
|
||||
@ -187,9 +234,9 @@ static void file_transfer_test(void)
|
||||
printf("Waiting for toxes to come online\n");
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
tox_iterate(tox3, nullptr);
|
||||
iterate_and_dispatch(dispatch1, tox1);
|
||||
iterate_and_dispatch(dispatch2, tox2);
|
||||
iterate_and_dispatch(dispatch3, tox3);
|
||||
|
||||
printf("Connections: self (%d, %d, %d), friends (%d, %d)\n",
|
||||
tox_self_get_connection_status(tox1),
|
||||
@ -210,11 +257,11 @@ static void file_transfer_test(void)
|
||||
file_recv = 0;
|
||||
max_sending = UINT64_MAX;
|
||||
uint64_t f_time = time(nullptr);
|
||||
tox_callback_file_recv_chunk(tox3, write_file);
|
||||
tox_callback_file_recv_control(tox2, file_print_control);
|
||||
tox_callback_file_chunk_request(tox2, tox_file_chunk_request);
|
||||
tox_callback_file_recv_control(tox3, file_print_control);
|
||||
tox_callback_file_recv(tox3, tox_file_receive);
|
||||
tox_events_callback_file_recv_chunk(dispatch3, write_file);
|
||||
tox_events_callback_file_recv_control(dispatch2, file_print_control);
|
||||
tox_events_callback_file_chunk_request(dispatch2, tox_file_chunk_request);
|
||||
tox_events_callback_file_recv_control(dispatch3, file_print_control);
|
||||
tox_events_callback_file_recv(dispatch3, tox_file_receive);
|
||||
uint64_t totalf_size = 100 * 1024 * 1024;
|
||||
uint32_t fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr, (const uint8_t *)"Gentoo.exe",
|
||||
sizeof("Gentoo.exe"), nullptr);
|
||||
@ -231,9 +278,9 @@ static void file_transfer_test(void)
|
||||
const size_t max_iterations = INT16_MAX;
|
||||
|
||||
for (size_t i = 0; i < max_iterations; i++) {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
tox_iterate(tox3, nullptr);
|
||||
iterate_and_dispatch(dispatch1, tox1);
|
||||
iterate_and_dispatch(dispatch2, tox2);
|
||||
iterate_and_dispatch(dispatch3, tox3);
|
||||
|
||||
if (file_sending_done) {
|
||||
ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size && sending_pos == size_recv
|
||||
@ -274,11 +321,11 @@ static void file_transfer_test(void)
|
||||
sendf_ok = 0;
|
||||
size_recv = 0;
|
||||
file_recv = 0;
|
||||
tox_callback_file_recv_chunk(tox3, write_file);
|
||||
tox_callback_file_recv_control(tox2, file_print_control);
|
||||
tox_callback_file_chunk_request(tox2, tox_file_chunk_request);
|
||||
tox_callback_file_recv_control(tox3, file_print_control);
|
||||
tox_callback_file_recv(tox3, tox_file_receive);
|
||||
tox_events_callback_file_recv_chunk(dispatch3, write_file);
|
||||
tox_events_callback_file_recv_control(dispatch2, file_print_control);
|
||||
tox_events_callback_file_chunk_request(dispatch2, tox_file_chunk_request);
|
||||
tox_events_callback_file_recv_control(dispatch3, file_print_control);
|
||||
tox_events_callback_file_recv(dispatch3, tox_file_receive);
|
||||
totalf_size = 0;
|
||||
fnum = tox_file_send(tox2, 0, TOX_FILE_KIND_DATA, totalf_size, nullptr,
|
||||
(const uint8_t *)"Gentoo.exe", sizeof("Gentoo.exe"), nullptr);
|
||||
@ -298,9 +345,9 @@ static void file_transfer_test(void)
|
||||
|
||||
c_sleep(min_u32(tox1_interval, min_u32(tox2_interval, tox3_interval)));
|
||||
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
tox_iterate(tox3, nullptr);
|
||||
iterate_and_dispatch(dispatch1, tox1);
|
||||
iterate_and_dispatch(dispatch2, tox2);
|
||||
iterate_and_dispatch(dispatch3, tox3);
|
||||
} while (!file_sending_done);
|
||||
|
||||
ck_assert_msg(sendf_ok && file_recv && totalf_size == file_size && size_recv == file_size
|
||||
@ -312,9 +359,12 @@ static void file_transfer_test(void)
|
||||
|
||||
printf("file_transfer_test succeeded, took %llu seconds\n", time(nullptr) - cur_time);
|
||||
|
||||
tox_kill(tox1);
|
||||
tox_kill(tox2);
|
||||
tox_dispatch_free(dispatch3);
|
||||
tox_dispatch_free(dispatch2);
|
||||
tox_dispatch_free(dispatch1);
|
||||
tox_kill(tox3);
|
||||
tox_kill(tox2);
|
||||
tox_kill(tox1);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
|
@ -47,8 +47,8 @@ static void test_forwarded_request_cb(void *object, const IP_Port *forwarder,
|
||||
const uint8_t *sendback, uint16_t sendback_length,
|
||||
const uint8_t *data, uint16_t length, void *userdata)
|
||||
{
|
||||
Test_Data *test_data = (Test_Data *)object;
|
||||
uint8_t *index = (uint8_t *)userdata;
|
||||
const Test_Data *test_data = (const Test_Data *)object;
|
||||
const uint8_t *index = (const uint8_t *)userdata;
|
||||
|
||||
if (length != 12 || memcmp("hello: ", data, 8) != 0) {
|
||||
printf("[%u] got unexpected data of length %d\n", *index, length);
|
||||
@ -66,7 +66,7 @@ static void test_forwarded_response_cb(void *object,
|
||||
const uint8_t *data, uint16_t length, void *userdata)
|
||||
{
|
||||
Test_Data *test_data = (Test_Data *)object;
|
||||
uint8_t *index = (uint8_t *)userdata;
|
||||
const uint8_t *index = (const uint8_t *)userdata;
|
||||
|
||||
if (length != 12 || memcmp("reply: ", data, 8) != 0) {
|
||||
printf("[%u] got unexpected data of length %d\n", *index, length);
|
||||
@ -104,9 +104,9 @@ typedef struct Forwarding_Subtox {
|
||||
|
||||
static Forwarding_Subtox *new_forwarding_subtox(const Memory *mem, bool no_udp, uint32_t *index, uint16_t port)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
|
||||
Forwarding_Subtox *subtox = (Forwarding_Subtox *)calloc(1, sizeof(Forwarding_Subtox));
|
||||
@ -152,11 +152,11 @@ static void kill_forwarding_subtox(const Memory *mem, Forwarding_Subtox *subtox)
|
||||
|
||||
static void test_forwarding(void)
|
||||
{
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
|
||||
uint32_t index[NUM_FORWARDER];
|
||||
@ -317,7 +317,6 @@ static void test_forwarding(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < NUM_FORWARDER; ++i) {
|
||||
kill_forwarding_subtox(mem, subtoxes[i]);
|
||||
}
|
||||
@ -325,7 +324,6 @@ static void test_forwarding(void)
|
||||
tox_kill(relay);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
|
@ -22,12 +22,18 @@ typedef struct State {
|
||||
bool unused;
|
||||
} State;
|
||||
|
||||
static void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, size_t length,
|
||||
static void accept_friend_request(const Tox_Event_Friend_Request *event,
|
||||
void *userdata)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)userdata;
|
||||
|
||||
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
|
||||
const uint8_t *data = tox_event_friend_request_get_message(event);
|
||||
const size_t length = tox_event_friend_request_get_message_length(event);
|
||||
|
||||
ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0,
|
||||
"unexpected friend request message");
|
||||
tox_friend_add_norequest(tox, public_key, nullptr);
|
||||
tox_friend_add_norequest(autotox->tox, public_key, nullptr);
|
||||
}
|
||||
|
||||
static void test_friend_request(AutoTox *autotoxes)
|
||||
@ -35,7 +41,7 @@ static void test_friend_request(AutoTox *autotoxes)
|
||||
const time_t con_time = time(nullptr);
|
||||
|
||||
printf("All toxes add tox1 as friend.\n");
|
||||
tox_callback_friend_request(autotoxes[0].tox, accept_friend_request);
|
||||
tox_events_callback_friend_request(autotoxes[0].dispatch, accept_friend_request);
|
||||
|
||||
uint8_t address[TOX_ADDRESS_SIZE];
|
||||
tox_self_get_address(autotoxes[0].tox, address);
|
||||
|
@ -15,12 +15,36 @@
|
||||
|
||||
#define FR_MESSAGE "Gentoo"
|
||||
|
||||
static void accept_friend_request(Tox *tox, const uint8_t *public_key, const uint8_t *data, size_t length,
|
||||
static void accept_friend_request(const Tox_Event_Friend_Request *event,
|
||||
void *userdata)
|
||||
{
|
||||
Tox *state_tox = (Tox *)userdata;
|
||||
|
||||
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
|
||||
const uint8_t *data = tox_event_friend_request_get_message(event);
|
||||
const size_t length = tox_event_friend_request_get_message_length(event);
|
||||
|
||||
ck_assert_msg(length == sizeof(FR_MESSAGE) && memcmp(FR_MESSAGE, data, sizeof(FR_MESSAGE)) == 0,
|
||||
"unexpected friend request message");
|
||||
tox_friend_add_norequest(tox, public_key, nullptr);
|
||||
tox_friend_add_norequest(state_tox, public_key, nullptr);
|
||||
}
|
||||
|
||||
static void iterate2_wait(const Tox_Dispatch *dispatch, Tox *tox1, Tox *tox2)
|
||||
{
|
||||
Tox_Err_Events_Iterate err;
|
||||
Tox_Events *events;
|
||||
|
||||
events = tox_events_iterate(tox1, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch, events, tox1);
|
||||
tox_events_free(events);
|
||||
|
||||
events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch, events, tox2);
|
||||
tox_events_free(events);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
static void test_friend_request(void)
|
||||
@ -33,6 +57,9 @@ static void test_friend_request(void)
|
||||
|
||||
ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances");
|
||||
|
||||
tox_events_init(tox1);
|
||||
tox_events_init(tox2);
|
||||
|
||||
printf("Bootstrapping tox2 off tox1.\n");
|
||||
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_dht_id(tox1, dht_key);
|
||||
@ -40,11 +67,11 @@ static void test_friend_request(void)
|
||||
|
||||
tox_bootstrap(tox2, "localhost", dht_port, dht_key, nullptr);
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch != nullptr);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
do {
|
||||
iterate2_wait(dispatch, tox1, tox2);
|
||||
} while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE ||
|
||||
tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE);
|
||||
|
||||
@ -52,7 +79,7 @@ static void test_friend_request(void)
|
||||
const time_t con_time = time(nullptr);
|
||||
|
||||
printf("Tox1 adds tox2 as friend, tox2 accepts.\n");
|
||||
tox_callback_friend_request(tox2, accept_friend_request);
|
||||
tox_events_callback_friend_request(dispatch, accept_friend_request);
|
||||
|
||||
uint8_t address[TOX_ADDRESS_SIZE];
|
||||
tox_self_get_address(tox2, address);
|
||||
@ -61,16 +88,14 @@ static void test_friend_request(void)
|
||||
ck_assert_msg(test == 0, "failed to add friend error code: %u", test);
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
iterate2_wait(dispatch, tox1, tox2);
|
||||
} while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP ||
|
||||
tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP);
|
||||
|
||||
printf("Tox clients connected took %lu seconds.\n", (unsigned long)(time(nullptr) - con_time));
|
||||
printf("friend_request_test succeeded, took %lu seconds.\n", (unsigned long)(time(nullptr) - cur_time));
|
||||
|
||||
tox_dispatch_free(dispatch);
|
||||
tox_kill(tox1);
|
||||
tox_kill(tox2);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ typedef struct State {
|
||||
|
||||
#define PEER_LIMIT 20
|
||||
|
||||
static void print_ip(Tox *tox, uint32_t groupnumber, uint32_t peer_id)
|
||||
static void print_ip(const Tox *tox, uint32_t groupnumber, uint32_t peer_id)
|
||||
{
|
||||
Tox_Err_Group_Peer_Query err;
|
||||
size_t length = tox_group_peer_get_ip_address_size(tox, groupnumber, peer_id, &err);
|
||||
@ -81,32 +81,35 @@ static bool all_group_peers_connected(AutoTox *autotoxes, uint32_t tox_count, ui
|
||||
return true;
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t groupnumber = tox_event_group_peer_join_get_group_number(event);
|
||||
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
|
||||
|
||||
// we do a connection test here for fun
|
||||
Tox_Err_Group_Peer_Query pq_err;
|
||||
TOX_CONNECTION connection_status = tox_group_peer_get_connection_status(tox, groupnumber, peer_id, &pq_err);
|
||||
Tox_Connection connection_status = tox_group_peer_get_connection_status(autotox->tox, groupnumber, peer_id, &pq_err);
|
||||
ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(connection_status != TOX_CONNECTION_NONE);
|
||||
|
||||
Tox_Group_Role role = tox_group_peer_get_role(tox, groupnumber, peer_id, &pq_err);
|
||||
Tox_Group_Role role = tox_group_peer_get_role(autotox->tox, groupnumber, peer_id, &pq_err);
|
||||
ck_assert_msg(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK, "%d", pq_err);
|
||||
|
||||
Tox_User_Status status = tox_group_peer_get_status(tox, groupnumber, peer_id, &pq_err);
|
||||
Tox_User_Status status = tox_group_peer_get_status(autotox->tox, groupnumber, peer_id, &pq_err);
|
||||
ck_assert_msg(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK, "%d", pq_err);
|
||||
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &pq_err);
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &pq_err);
|
||||
char peer_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
|
||||
ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &pq_err);
|
||||
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &pq_err);
|
||||
ck_assert(pq_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
|
||||
peer_name[peer_name_len] = 0;
|
||||
@ -137,35 +140,37 @@ static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t pee
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s joined with IP: ", peer_name);
|
||||
print_ip(tox, groupnumber, peer_id);
|
||||
print_ip(autotox->tox, groupnumber, peer_id);
|
||||
|
||||
state->peer_id = peer_id;
|
||||
++state->peer_joined_count;
|
||||
}
|
||||
|
||||
static void group_peer_self_join_handler(Tox *tox, uint32_t groupnumber, void *user_data)
|
||||
static void group_peer_self_join_handler(const Tox_Event_Group_Self_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t groupnumber = tox_event_group_self_join_get_group_number(event);
|
||||
|
||||
// make sure we see our own correct peer state on join callback
|
||||
|
||||
Tox_Err_Group_Self_Query sq_err;
|
||||
size_t self_length = tox_group_self_get_name_size(tox, groupnumber, &sq_err);
|
||||
size_t self_length = tox_group_self_get_name_size(autotox->tox, groupnumber, &sq_err);
|
||||
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
|
||||
uint8_t self_name[TOX_MAX_NAME_LENGTH];
|
||||
tox_group_self_get_name(tox, groupnumber, self_name, &sq_err);
|
||||
tox_group_self_get_name(autotox->tox, groupnumber, self_name, &sq_err);
|
||||
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
|
||||
TOX_USER_STATUS self_status = tox_group_self_get_status(tox, groupnumber, &sq_err);
|
||||
Tox_User_Status self_status = tox_group_self_get_status(autotox->tox, groupnumber, &sq_err);
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
|
||||
Tox_Group_Role self_role = tox_group_self_get_role(tox, groupnumber, &sq_err);
|
||||
Tox_Group_Role self_role = tox_group_self_get_role(autotox->tox, groupnumber, &sq_err);
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
|
||||
if (state->is_founder) {
|
||||
@ -185,36 +190,37 @@ static void group_peer_self_join_handler(Tox *tox, uint32_t groupnumber, void *u
|
||||
uint8_t group_name[GROUP_NAME_LEN];
|
||||
uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH];
|
||||
|
||||
ck_assert(tox_group_get_peer_limit(tox, groupnumber, nullptr) == PEER_LIMIT);
|
||||
ck_assert(tox_group_get_name_size(tox, groupnumber, nullptr) == GROUP_NAME_LEN);
|
||||
ck_assert(tox_group_get_topic_size(tox, groupnumber, nullptr) == TOPIC_LEN);
|
||||
ck_assert(tox_group_get_peer_limit(autotox->tox, groupnumber, nullptr) == PEER_LIMIT);
|
||||
ck_assert(tox_group_get_name_size(autotox->tox, groupnumber, nullptr) == GROUP_NAME_LEN);
|
||||
ck_assert(tox_group_get_topic_size(autotox->tox, groupnumber, nullptr) == TOPIC_LEN);
|
||||
|
||||
Tox_Err_Group_State_Queries query_err;
|
||||
tox_group_get_name(tox, groupnumber, group_name, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err);
|
||||
Tox_Err_Group_State_Query query_err;
|
||||
tox_group_get_name(autotox->tox, groupnumber, group_name, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", query_err);
|
||||
ck_assert(memcmp(group_name, GROUP_NAME, GROUP_NAME_LEN) == 0);
|
||||
|
||||
tox_group_get_topic(tox, groupnumber, topic, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", query_err);
|
||||
tox_group_get_topic(autotox->tox, groupnumber, topic, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", query_err);
|
||||
ck_assert(memcmp(topic, TOPIC, TOPIC_LEN) == 0);
|
||||
|
||||
uint32_t peer_id = tox_group_self_get_peer_id(tox, groupnumber, nullptr);
|
||||
uint32_t peer_id = tox_group_self_get_peer_id(autotox->tox, groupnumber, nullptr);
|
||||
|
||||
fprintf(stderr, "self joined with IP: ");
|
||||
print_ip(tox, groupnumber, peer_id);
|
||||
print_ip(autotox->tox, groupnumber, peer_id);
|
||||
|
||||
++state->self_joined_count;
|
||||
}
|
||||
|
||||
static void group_peer_exit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type,
|
||||
const uint8_t *name, size_t name_length, const uint8_t *part_message,
|
||||
size_t length, void *user_data)
|
||||
static void group_peer_exit_handler(const Tox_Event_Group_Peer_Exit *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint8_t *part_message = tox_event_group_peer_exit_get_part_message(event);
|
||||
const size_t length = tox_event_group_peer_exit_get_part_message_length(event);
|
||||
|
||||
++state->peer_exit_count;
|
||||
|
||||
// first exit is a disconnect. second is a real exit with a part message
|
||||
@ -224,14 +230,16 @@ static void group_peer_exit_handler(Tox *tox, uint32_t groupnumber, uint32_t pee
|
||||
}
|
||||
}
|
||||
|
||||
static void group_peer_name_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *name,
|
||||
size_t length, void *user_data)
|
||||
static void group_peer_name_handler(const Tox_Event_Group_Peer_Name *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint8_t *name = tox_event_group_peer_name_get_name(event);
|
||||
const size_t length = tox_event_group_peer_name_get_name_length(event);
|
||||
|
||||
// note: we already test the name_get api call elsewhere
|
||||
|
||||
ck_assert(length == PEER0_NICK2_LEN);
|
||||
@ -240,7 +248,7 @@ static void group_peer_name_handler(Tox *tox, uint32_t groupnumber, uint32_t pee
|
||||
state->peer_nick = true;
|
||||
}
|
||||
|
||||
static void group_peer_status_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_USER_STATUS status,
|
||||
static void group_peer_status_handler(const Tox_Event_Group_Peer_Status *event,
|
||||
void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
@ -248,8 +256,12 @@ static void group_peer_status_handler(Tox *tox, uint32_t groupnumber, uint32_t p
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t groupnumber = tox_event_group_peer_status_get_group_number(event);
|
||||
const uint32_t peer_id = tox_event_group_peer_status_get_peer_id(event);
|
||||
const Tox_User_Status status = tox_event_group_peer_status_get_status(event);
|
||||
|
||||
Tox_Err_Group_Peer_Query err;
|
||||
TOX_USER_STATUS cur_status = tox_group_peer_get_status(tox, groupnumber, peer_id, &err);
|
||||
Tox_User_Status cur_status = tox_group_peer_get_status(autotox->tox, groupnumber, peer_id, &err);
|
||||
|
||||
ck_assert_msg(cur_status == status, "%d, %d", cur_status, status);
|
||||
ck_assert(status == TOX_USER_STATUS_BUSY);
|
||||
@ -264,15 +276,15 @@ static void group_announce_test(AutoTox *autotoxes)
|
||||
Tox *tox0 = autotoxes[0].tox;
|
||||
Tox *tox1 = autotoxes[1].tox;
|
||||
State *state0 = (State *)autotoxes[0].state;
|
||||
State *state1 = (State *)autotoxes[1].state;
|
||||
const State *state1 = (const State *)autotoxes[1].state;
|
||||
|
||||
tox_callback_group_peer_join(tox0, group_peer_join_handler);
|
||||
tox_callback_group_peer_join(tox1, group_peer_join_handler);
|
||||
tox_callback_group_self_join(tox0, group_peer_self_join_handler);
|
||||
tox_callback_group_self_join(tox1, group_peer_self_join_handler);
|
||||
tox_callback_group_peer_name(tox1, group_peer_name_handler);
|
||||
tox_callback_group_peer_status(tox1, group_peer_status_handler);
|
||||
tox_callback_group_peer_exit(tox1, group_peer_exit_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[0].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[1].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_self_join(autotoxes[0].dispatch, group_peer_self_join_handler);
|
||||
tox_events_callback_group_self_join(autotoxes[1].dispatch, group_peer_self_join_handler);
|
||||
tox_events_callback_group_peer_name(autotoxes[1].dispatch, group_peer_name_handler);
|
||||
tox_events_callback_group_peer_status(autotoxes[1].dispatch, group_peer_status_handler);
|
||||
tox_events_callback_group_peer_exit(autotoxes[1].dispatch, group_peer_exit_handler);
|
||||
|
||||
// tox0 makes new group.
|
||||
Tox_Err_Group_New err_new;
|
||||
@ -286,19 +298,19 @@ static void group_announce_test(AutoTox *autotoxes)
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
|
||||
// changes the state (for sync check purposes)
|
||||
Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err;
|
||||
tox_group_founder_set_peer_limit(tox0, groupnumber, PEER_LIMIT, &limit_set_err);
|
||||
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err);
|
||||
Tox_Err_Group_Set_Peer_Limit limit_set_err;
|
||||
tox_group_set_peer_limit(tox0, groupnumber, PEER_LIMIT, &limit_set_err);
|
||||
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err);
|
||||
|
||||
Tox_Err_Group_Topic_Set tp_err;
|
||||
tox_group_set_topic(tox0, groupnumber, (const uint8_t *)TOPIC, TOPIC_LEN, &tp_err);
|
||||
ck_assert(tp_err == TOX_ERR_GROUP_TOPIC_SET_OK);
|
||||
|
||||
// get the chat id of the new group.
|
||||
Tox_Err_Group_State_Queries err_id;
|
||||
Tox_Err_Group_State_Query err_id;
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
tox_group_get_chat_id(tox0, groupnumber, chat_id, &err_id);
|
||||
ck_assert(err_id == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(err_id == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
// tox1 joins it.
|
||||
Tox_Err_Group_Join err_join;
|
||||
@ -343,7 +355,7 @@ static void group_announce_test(AutoTox *autotoxes)
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
|
||||
TOX_USER_STATUS self_status = tox_group_self_get_status(tox0, groupnumber, &sq_err);
|
||||
Tox_User_Status self_status = tox_group_self_get_status(tox0, groupnumber, &sq_err);
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
ck_assert(self_status == TOX_USER_STATUS_BUSY);
|
||||
|
||||
@ -429,10 +441,12 @@ static void group_announce_test(AutoTox *autotoxes)
|
||||
tox_group_leave(tox1, groupnumber, nullptr, 0, &err_exit);
|
||||
ck_assert(err_exit == TOX_ERR_GROUP_LEAVE_OK);
|
||||
|
||||
num_groups1 = tox_group_get_number_groups(tox0);
|
||||
num_groups2 = tox_group_get_number_groups(tox1);
|
||||
while (num_groups1 != 0 || num_groups2 != 0) {
|
||||
num_groups1 = tox_group_get_number_groups(tox0);
|
||||
num_groups2 = tox_group_get_number_groups(tox1);
|
||||
|
||||
ck_assert(num_groups1 == num_groups2 && num_groups2 == 0);
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
printf("All tests passed!\n");
|
||||
}
|
||||
|
@ -51,13 +51,15 @@ static bool group_has_full_graph(const AutoTox *autotoxes, uint32_t group_number
|
||||
return true;
|
||||
}
|
||||
|
||||
static void group_join_fail_handler(Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, void *user_data)
|
||||
static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event);
|
||||
|
||||
switch (fail_type) {
|
||||
case TOX_GROUP_JOIN_FAIL_PEER_LIMIT: {
|
||||
state->peer_limit_fail = true;
|
||||
@ -79,7 +81,7 @@ static void group_join_fail_handler(Tox *tox, uint32_t group_number, Tox_Group_J
|
||||
}
|
||||
}
|
||||
|
||||
static void group_self_join_handler(Tox *tox, uint32_t group_number, void *user_data)
|
||||
static void group_self_join_handler(const Tox_Event_Group_Self_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
@ -89,7 +91,7 @@ static void group_self_join_handler(Tox *tox, uint32_t group_number, void *user_
|
||||
state->connected = true;
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
@ -105,9 +107,9 @@ static void group_invite_test(AutoTox *autotoxes)
|
||||
ck_assert_msg(NUM_GROUP_TOXES > 7, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
|
||||
tox_callback_group_join_fail(autotoxes[i].tox, group_join_fail_handler);
|
||||
tox_callback_group_self_join(autotoxes[i].tox, group_self_join_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_join_fail(autotoxes[i].dispatch, group_join_fail_handler);
|
||||
tox_events_callback_group_self_join(autotoxes[i].dispatch, group_self_join_handler);
|
||||
}
|
||||
|
||||
Tox *tox0 = autotoxes[0].tox;
|
||||
@ -118,12 +120,12 @@ static void group_invite_test(AutoTox *autotoxes)
|
||||
Tox *tox5 = autotoxes[5].tox;
|
||||
Tox *tox6 = autotoxes[6].tox;
|
||||
|
||||
State *state0 = (State *)autotoxes[0].state;
|
||||
State *state2 = (State *)autotoxes[2].state;
|
||||
State *state3 = (State *)autotoxes[3].state;
|
||||
State *state4 = (State *)autotoxes[4].state;
|
||||
State *state5 = (State *)autotoxes[5].state;
|
||||
State *state6 = (State *)autotoxes[6].state;
|
||||
const State *state0 = (const State *)autotoxes[0].state;
|
||||
const State *state2 = (const State *)autotoxes[2].state;
|
||||
const State *state3 = (const State *)autotoxes[3].state;
|
||||
const State *state4 = (const State *)autotoxes[4].state;
|
||||
const State *state5 = (const State *)autotoxes[5].state;
|
||||
const State *state6 = (const State *)autotoxes[6].state;
|
||||
|
||||
Tox_Err_Group_New new_err;
|
||||
uint32_t groupnumber = tox_group_new(tox0, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4,
|
||||
@ -132,11 +134,11 @@ static void group_invite_test(AutoTox *autotoxes)
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
|
||||
Tox_Err_Group_State_Queries id_err;
|
||||
Tox_Err_Group_State_Query id_err;
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
|
||||
tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err);
|
||||
|
||||
// peer 1 joins public group with no password
|
||||
Tox_Err_Group_Join join_err;
|
||||
@ -150,9 +152,9 @@ static void group_invite_test(AutoTox *autotoxes)
|
||||
printf("Peer 1 joined group\n");
|
||||
|
||||
// founder sets a password
|
||||
Tox_Err_Group_Founder_Set_Password pass_set_err;
|
||||
tox_group_founder_set_password(tox0, groupnumber, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err);
|
||||
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "%d", pass_set_err);
|
||||
Tox_Err_Group_Set_Password pass_set_err;
|
||||
tox_group_set_password(tox0, groupnumber, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err);
|
||||
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "%d", pass_set_err);
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000);
|
||||
|
||||
@ -177,9 +179,9 @@ static void group_invite_test(AutoTox *autotoxes)
|
||||
printf("Peer 3 successfully blocked with invalid password\n");
|
||||
|
||||
// founder sets peer limit to 1
|
||||
Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err;
|
||||
tox_group_founder_set_peer_limit(tox0, groupnumber, 1, &limit_set_err);
|
||||
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "%d", limit_set_err);
|
||||
Tox_Err_Group_Set_Peer_Limit limit_set_err;
|
||||
tox_group_set_peer_limit(tox0, groupnumber, 1, &limit_set_err);
|
||||
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "%d", limit_set_err);
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000);
|
||||
|
||||
@ -194,11 +196,11 @@ static void group_invite_test(AutoTox *autotoxes)
|
||||
printf("Peer 4 successfully blocked from joining full group\n");
|
||||
|
||||
// founder removes password and increases peer limit to 100
|
||||
tox_group_founder_set_password(tox0, groupnumber, nullptr, 0, &pass_set_err);
|
||||
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "%d", pass_set_err);
|
||||
tox_group_set_password(tox0, groupnumber, nullptr, 0, &pass_set_err);
|
||||
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "%d", pass_set_err);
|
||||
|
||||
tox_group_founder_set_peer_limit(tox0, groupnumber, 100, &limit_set_err);
|
||||
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "%d", limit_set_err);
|
||||
tox_group_set_peer_limit(tox0, groupnumber, 100, &limit_set_err);
|
||||
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "%d", limit_set_err);
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000);
|
||||
|
||||
@ -213,9 +215,9 @@ static void group_invite_test(AutoTox *autotoxes)
|
||||
printf("Peer 5 successfully joined the group\n");
|
||||
|
||||
// founder makes group private
|
||||
Tox_Err_Group_Founder_Set_Privacy_State priv_err;
|
||||
tox_group_founder_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PRIVATE, &priv_err);
|
||||
ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "%d", priv_err);
|
||||
Tox_Err_Group_Set_Privacy_State priv_err;
|
||||
tox_group_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PRIVATE, &priv_err);
|
||||
ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "%d", priv_err);
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, 5000);
|
||||
|
||||
@ -231,8 +233,8 @@ static void group_invite_test(AutoTox *autotoxes)
|
||||
printf("Peer 6 failed to join private group via chat ID\n");
|
||||
|
||||
// founder makes group public again
|
||||
tox_group_founder_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PUBLIC, &priv_err);
|
||||
ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "%d", priv_err);
|
||||
tox_group_set_privacy_state(tox0, groupnumber, TOX_GROUP_PRIVACY_STATE_PUBLIC, &priv_err);
|
||||
ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "%d", priv_err);
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
|
||||
|
@ -19,7 +19,7 @@ typedef struct State {
|
||||
bool peer_joined;
|
||||
bool message_sent;
|
||||
bool message_received;
|
||||
uint32_t pseudo_msg_id;
|
||||
Tox_Group_Message_Id pseudo_msg_id;
|
||||
bool private_message_received;
|
||||
size_t custom_packets_received;
|
||||
size_t custom_private_packets_received;
|
||||
@ -71,28 +71,37 @@ static uint16_t get_message_checksum(const uint8_t *message, uint16_t length)
|
||||
return sum;
|
||||
}
|
||||
|
||||
static void group_invite_handler(Tox *tox, 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)
|
||||
static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
const uint32_t friend_number = tox_event_group_invite_get_friend_number(event);
|
||||
const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event);
|
||||
const size_t length = tox_event_group_invite_get_invite_data_length(event);
|
||||
|
||||
printf("invite arrived; accepting\n");
|
||||
Tox_Err_Group_Invite_Accept err_accept;
|
||||
tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN,
|
||||
tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)PEER0_NICK, PEER0_NICK_LEN,
|
||||
nullptr, 0, &err_accept);
|
||||
ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK);
|
||||
}
|
||||
|
||||
static void group_join_fail_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Join_Fail fail_type, void *user_data)
|
||||
static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data)
|
||||
{
|
||||
const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event);
|
||||
printf("join failed: %d\n", fail_type);
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
|
||||
|
||||
ck_assert_msg(state->peer_joined == false, "Peer timedout");
|
||||
|
||||
printf("peer %u joined, sending message\n", peer_id);
|
||||
@ -100,9 +109,16 @@ static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t pee
|
||||
state->peer_id = peer_id;
|
||||
}
|
||||
|
||||
static void group_custom_private_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data,
|
||||
size_t length, void *user_data)
|
||||
static void group_custom_private_packet_handler(const Tox_Event_Group_Custom_Private_Packet *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
const uint32_t groupnumber = tox_event_group_custom_private_packet_get_group_number(event);
|
||||
const uint32_t peer_id = tox_event_group_custom_private_packet_get_peer_id(event);
|
||||
const uint8_t *data = tox_event_group_custom_private_packet_get_data(event);
|
||||
const size_t length = tox_event_group_custom_private_packet_get_data_length(event);
|
||||
|
||||
ck_assert_msg(length == TEST_CUSTOM_PRIVATE_PACKET_LEN,
|
||||
"Failed to receive custom private packet. Invalid length: %zu\n", length);
|
||||
|
||||
@ -111,25 +127,25 @@ static void group_custom_private_packet_handler(Tox *tox, uint32_t groupnumber,
|
||||
message_buf[length] = 0;
|
||||
|
||||
Tox_Err_Group_Peer_Query q_err;
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err);
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
char peer_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
|
||||
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
|
||||
peer_name[peer_name_len] = 0;
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
|
||||
|
||||
Tox_Err_Group_Self_Query s_err;
|
||||
size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
|
||||
size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err);
|
||||
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
char self_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
|
||||
tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err);
|
||||
self_name[self_name_len] = 0;
|
||||
|
||||
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
@ -138,17 +154,21 @@ static void group_custom_private_packet_handler(Tox *tox, uint32_t groupnumber,
|
||||
printf("%s sent custom private packet to %s: %s\n", peer_name, self_name, message_buf);
|
||||
ck_assert(memcmp(message_buf, TEST_CUSTOM_PRIVATE_PACKET, length) == 0);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
++state->custom_private_packets_received;
|
||||
}
|
||||
|
||||
static void group_custom_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data,
|
||||
size_t length, void *user_data)
|
||||
static void group_custom_packet_handler(const Tox_Event_Group_Custom_Packet *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
const uint32_t groupnumber = tox_event_group_custom_packet_get_group_number(event);
|
||||
const uint32_t peer_id = tox_event_group_custom_packet_get_peer_id(event);
|
||||
const uint8_t *data = tox_event_group_custom_packet_get_data(event);
|
||||
const size_t length = tox_event_group_custom_packet_get_data_length(event);
|
||||
|
||||
ck_assert_msg(length == TEST_CUSTOM_PACKET_LEN, "Failed to receive custom packet. Invalid length: %zu\n", length);
|
||||
|
||||
char message_buf[TOX_MAX_CUSTOM_PACKET_SIZE + 1];
|
||||
@ -156,25 +176,25 @@ static void group_custom_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t
|
||||
message_buf[length] = 0;
|
||||
|
||||
Tox_Err_Group_Peer_Query q_err;
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err);
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
char peer_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
|
||||
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err);
|
||||
peer_name[peer_name_len] = 0;
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
|
||||
|
||||
Tox_Err_Group_Self_Query s_err;
|
||||
size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
|
||||
size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err);
|
||||
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
char self_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
|
||||
tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err);
|
||||
self_name[self_name_len] = 0;
|
||||
|
||||
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
@ -183,32 +203,39 @@ static void group_custom_packet_handler(Tox *tox, uint32_t groupnumber, uint32_t
|
||||
printf("%s sent custom packet to %s: %s\n", peer_name, self_name, message_buf);
|
||||
ck_assert(memcmp(message_buf, TEST_CUSTOM_PACKET, length) == 0);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
++state->custom_packets_received;
|
||||
}
|
||||
|
||||
static void group_custom_packet_large_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *data,
|
||||
size_t length, void *user_data)
|
||||
static void group_custom_packet_large_handler(const Tox_Event_Group_Custom_Packet *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
const uint8_t *data = tox_event_group_custom_packet_get_data(event);
|
||||
const size_t length = tox_event_group_custom_packet_get_data_length(event);
|
||||
|
||||
ck_assert_msg(length == TEST_CUSTOM_PACKET_LARGE_LEN, "Failed to receive large custom packet. Invalid length: %zu\n", length);
|
||||
|
||||
ck_assert(memcmp(data, TEST_CUSTOM_PACKET_LARGE, length) == 0);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
++state->custom_packets_received;
|
||||
}
|
||||
|
||||
static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
|
||||
const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data)
|
||||
static void group_message_handler(const Tox_Event_Group_Message *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
const uint32_t groupnumber = tox_event_group_message_get_group_number(event);
|
||||
const uint32_t peer_id = tox_event_group_message_get_peer_id(event);
|
||||
const uint8_t *message = tox_event_group_message_get_message(event);
|
||||
const size_t length = tox_event_group_message_get_message_length(event);
|
||||
const uint32_t pseudo_msg_id = tox_event_group_message_get_message_id(event);
|
||||
|
||||
ck_assert(!(length == IGNORE_MESSAGE_LEN && memcmp(message, IGNORE_MESSAGE, length) == 0));
|
||||
ck_assert_msg(length == TEST_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length);
|
||||
|
||||
@ -217,25 +244,25 @@ static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_
|
||||
message_buf[length] = 0;
|
||||
|
||||
Tox_Err_Group_Peer_Query q_err;
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err);
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
char peer_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
|
||||
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err);
|
||||
peer_name[peer_name_len] = 0;
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
|
||||
|
||||
Tox_Err_Group_Self_Query s_err;
|
||||
size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
|
||||
size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err);
|
||||
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
char self_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
|
||||
tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err);
|
||||
self_name[self_name_len] = 0;
|
||||
|
||||
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
@ -244,19 +271,24 @@ static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_
|
||||
printf("%s sent message to %s:(id:%u) %s\n", peer_name, self_name, pseudo_msg_id, message_buf);
|
||||
ck_assert(memcmp(message_buf, TEST_MESSAGE, length) == 0);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
state->message_received = true;
|
||||
|
||||
state->pseudo_msg_id = pseudo_msg_id;
|
||||
}
|
||||
|
||||
static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
|
||||
const uint8_t *message, size_t length, void *user_data)
|
||||
static void group_private_message_handler(const Tox_Event_Group_Private_Message *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
const uint32_t groupnumber = tox_event_group_private_message_get_group_number(event);
|
||||
const uint32_t peer_id = tox_event_group_private_message_get_peer_id(event);
|
||||
const Tox_Message_Type type = tox_event_group_private_message_get_type(event);
|
||||
const uint8_t *message = tox_event_group_private_message_get_message(event);
|
||||
const size_t length = tox_event_group_private_message_get_message_length(event);
|
||||
const Tox_Group_Message_Id pseudo_msg_id = tox_event_group_private_message_get_message_id(event);
|
||||
|
||||
ck_assert_msg(length == TEST_PRIVATE_MESSAGE_LEN, "Failed to receive message. Invalid length: %zu\n", length);
|
||||
|
||||
char message_buf[TOX_GROUP_MAX_MESSAGE_LENGTH + 1];
|
||||
@ -264,46 +296,46 @@ static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32
|
||||
message_buf[length] = 0;
|
||||
|
||||
Tox_Err_Group_Peer_Query q_err;
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(tox, groupnumber, peer_id, &q_err);
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, groupnumber, peer_id, &q_err);
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
char peer_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
tox_group_peer_get_name(tox, groupnumber, peer_id, (uint8_t *) peer_name, &q_err);
|
||||
tox_group_peer_get_name(autotox->tox, groupnumber, peer_id, (uint8_t *)peer_name, &q_err);
|
||||
peer_name[peer_name_len] = 0;
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(memcmp(peer_name, PEER0_NICK, peer_name_len) == 0);
|
||||
|
||||
Tox_Err_Group_Self_Query s_err;
|
||||
size_t self_name_len = tox_group_self_get_name_size(tox, groupnumber, &s_err);
|
||||
size_t self_name_len = tox_group_self_get_name_size(autotox->tox, groupnumber, &s_err);
|
||||
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
ck_assert(self_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
char self_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
tox_group_self_get_name(tox, groupnumber, (uint8_t *) self_name, &s_err);
|
||||
tox_group_self_get_name(autotox->tox, groupnumber, (uint8_t *)self_name, &s_err);
|
||||
self_name[self_name_len] = 0;
|
||||
|
||||
ck_assert(s_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
ck_assert(memcmp(self_name, PEER1_NICK, self_name_len) == 0);
|
||||
|
||||
printf("%s sent private action to %s: %s\n", peer_name, self_name, message_buf);
|
||||
printf("%s sent private action to %s:(id: %u) %s\n", peer_name, self_name, pseudo_msg_id, message_buf);
|
||||
ck_assert(memcmp(message_buf, TEST_PRIVATE_MESSAGE, length) == 0);
|
||||
|
||||
ck_assert(type == TOX_MESSAGE_TYPE_ACTION);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
state->private_message_received = true;
|
||||
state->pseudo_msg_id = pseudo_msg_id;
|
||||
}
|
||||
|
||||
static void group_message_handler_lossless_test(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
|
||||
const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data)
|
||||
static void group_message_handler_lossless_test(const Tox_Event_Group_Message *event, void *user_data)
|
||||
{
|
||||
const uint8_t *message = tox_event_group_message_get_message(event);
|
||||
const size_t length = tox_event_group_message_get_message_length(event);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
@ -325,10 +357,11 @@ static void group_message_handler_lossless_test(Tox *tox, uint32_t groupnumber,
|
||||
state->lossless_check = true;
|
||||
}
|
||||
}
|
||||
static void group_message_handler_wraparound_test(Tox *tox, uint32_t groupnumber, uint32_t peer_id,
|
||||
TOX_MESSAGE_TYPE type,
|
||||
const uint8_t *message, size_t length, uint32_t pseudo_msg_id, void *user_data)
|
||||
static void group_message_handler_wraparound_test(const Tox_Event_Group_Message *event, void *user_data)
|
||||
{
|
||||
const uint8_t *message = tox_event_group_message_get_message(event);
|
||||
const size_t length = tox_event_group_message_get_message_length(event);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
@ -352,11 +385,11 @@ static void group_message_test(AutoTox *autotoxes)
|
||||
{
|
||||
ck_assert_msg(NUM_GROUP_TOXES >= 2, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
|
||||
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
Tox *tox0 = autotoxes[0].tox;
|
||||
Tox *tox1 = autotoxes[1].tox;
|
||||
const Tox *tox1 = autotoxes[1].tox;
|
||||
|
||||
State *state0 = (State *)autotoxes[0].state;
|
||||
State *state1 = (State *)autotoxes[1].state;
|
||||
@ -365,15 +398,15 @@ static void group_message_test(AutoTox *autotoxes)
|
||||
state0->pseudo_msg_id = 0;
|
||||
state1->pseudo_msg_id = 1;
|
||||
|
||||
tox_callback_group_invite(tox1, group_invite_handler);
|
||||
tox_callback_group_join_fail(tox1, group_join_fail_handler);
|
||||
tox_callback_group_peer_join(tox1, group_peer_join_handler);
|
||||
tox_callback_group_join_fail(tox0, group_join_fail_handler);
|
||||
tox_callback_group_peer_join(tox0, group_peer_join_handler);
|
||||
tox_callback_group_message(tox0, group_message_handler);
|
||||
tox_callback_group_custom_packet(tox0, group_custom_packet_handler);
|
||||
tox_callback_group_custom_private_packet(tox0, group_custom_private_packet_handler);
|
||||
tox_callback_group_private_message(tox0, group_private_message_handler);
|
||||
tox_events_callback_group_invite(autotoxes[1].dispatch, group_invite_handler);
|
||||
tox_events_callback_group_join_fail(autotoxes[1].dispatch, group_join_fail_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[1].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_join_fail(autotoxes[0].dispatch, group_join_fail_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[0].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_message(autotoxes[0].dispatch, group_message_handler);
|
||||
tox_events_callback_group_custom_packet(autotoxes[0].dispatch, group_custom_packet_handler);
|
||||
tox_events_callback_group_custom_private_packet(autotoxes[0].dispatch, group_custom_private_packet_handler);
|
||||
tox_events_callback_group_private_message(autotoxes[0].dispatch, group_private_message_handler);
|
||||
|
||||
Tox_Err_Group_Send_Message err_send;
|
||||
|
||||
@ -396,14 +429,15 @@ static void group_message_test(AutoTox *autotoxes)
|
||||
|
||||
if (state1->peer_joined && !state1->message_sent) {
|
||||
state1->pseudo_msg_id = tox_group_send_message(
|
||||
tox1, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)TEST_MESSAGE,
|
||||
TEST_MESSAGE_LEN, &err_send);
|
||||
tox1, group_number, TOX_MESSAGE_TYPE_NORMAL, (const uint8_t *)TEST_MESSAGE,
|
||||
TEST_MESSAGE_LEN, &err_send);
|
||||
ck_assert(err_send == TOX_ERR_GROUP_SEND_MESSAGE_OK);
|
||||
state1->message_sent = true;
|
||||
}
|
||||
}
|
||||
|
||||
ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u", state0->pseudo_msg_id, state1->pseudo_msg_id);
|
||||
ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u",
|
||||
state0->pseudo_msg_id, state1->pseudo_msg_id);
|
||||
|
||||
// Make sure we're still connected to each friend
|
||||
Tox_Connection conn_1 = tox_friend_get_connection_status(tox0, 0, nullptr);
|
||||
@ -428,14 +462,23 @@ static void group_message_test(AutoTox *autotoxes)
|
||||
tox_group_set_ignore(tox0, group_number, state0->peer_id, false, &ig_err);
|
||||
ck_assert_msg(ig_err == TOX_ERR_GROUP_SET_IGNORE_OK, "%d", ig_err);
|
||||
|
||||
fprintf(stderr, "Sending private message...\n");
|
||||
fprintf(stderr, "Sending private action...\n");
|
||||
|
||||
// tox0 sends a private action to tox1
|
||||
// tox1 sends a private action to tox0
|
||||
Tox_Err_Group_Send_Private_Message m_err;
|
||||
tox_group_send_private_message(tox1, group_number, state1->peer_id, TOX_MESSAGE_TYPE_ACTION,
|
||||
(const uint8_t *)TEST_PRIVATE_MESSAGE, TEST_PRIVATE_MESSAGE_LEN, &m_err);
|
||||
state1->pseudo_msg_id = tox_group_send_private_message(tox1, group_number, state1->peer_id,
|
||||
TOX_MESSAGE_TYPE_ACTION, (const uint8_t *)TEST_PRIVATE_MESSAGE,
|
||||
TEST_PRIVATE_MESSAGE_LEN, &m_err);
|
||||
|
||||
ck_assert_msg(m_err == TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK, "%d", m_err);
|
||||
|
||||
while (!state0->private_message_received) {
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
ck_assert_msg(state0->pseudo_msg_id == state1->pseudo_msg_id, "id0:%u id1:%u",
|
||||
state0->pseudo_msg_id, state1->pseudo_msg_id);
|
||||
|
||||
fprintf(stderr, "Sending custom packets...\n");
|
||||
|
||||
// tox0 sends a lossless and lossy custom packet to tox1
|
||||
@ -464,15 +507,14 @@ static void group_message_test(AutoTox *autotoxes)
|
||||
|
||||
ck_assert_msg(cperr == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK, "%d", cperr);
|
||||
|
||||
while (!state0->private_message_received || state0->custom_packets_received < 2
|
||||
|| state0->custom_private_packets_received < 2) {
|
||||
while (state0->custom_packets_received < 2 || state0->custom_private_packets_received < 2) {
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
}
|
||||
|
||||
// tox0 sends a large max sized lossy custom packet
|
||||
|
||||
// overwrite callback for larger packet
|
||||
tox_callback_group_custom_packet(tox0, group_custom_packet_large_handler);
|
||||
tox_events_callback_group_custom_packet(autotoxes[0].dispatch, group_custom_packet_large_handler);
|
||||
|
||||
tox_group_send_custom_packet(tox1, group_number, false, (const uint8_t *)TEST_CUSTOM_PACKET_LARGE, TEST_CUSTOM_PACKET_LARGE_LEN,
|
||||
&c_err);
|
||||
@ -486,7 +528,7 @@ static void group_message_test(AutoTox *autotoxes)
|
||||
|
||||
fprintf(stderr, "Doing lossless packet test...\n");
|
||||
|
||||
tox_callback_group_message(tox1, group_message_handler_lossless_test);
|
||||
tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler_lossless_test);
|
||||
state1->last_msg_recv = -1;
|
||||
|
||||
// lossless and packet splitting/reassembly test
|
||||
@ -517,7 +559,7 @@ static void group_message_test(AutoTox *autotoxes)
|
||||
}
|
||||
|
||||
state1->last_msg_recv = -1;
|
||||
tox_callback_group_message(tox1, group_message_handler_wraparound_test);
|
||||
tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler_wraparound_test);
|
||||
|
||||
fprintf(stderr, "Doing wraparound test...\n");
|
||||
|
||||
|
@ -19,13 +19,13 @@
|
||||
#define GROUP_NAME_LEN (sizeof(GROUP_NAME) - 1)
|
||||
|
||||
typedef struct Peer {
|
||||
char name[TOX_MAX_NAME_LENGTH];
|
||||
char name[TOX_MAX_NAME_LENGTH + 1];
|
||||
size_t name_length;
|
||||
uint32_t peer_id;
|
||||
} Peer;
|
||||
|
||||
typedef struct State {
|
||||
char self_name[TOX_MAX_NAME_LENGTH];
|
||||
char self_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
size_t self_name_length;
|
||||
|
||||
uint32_t group_number;
|
||||
@ -38,7 +38,6 @@ typedef struct State {
|
||||
char mod_name1[TOX_MAX_NAME_LENGTH];
|
||||
char mod_name2[TOX_MAX_NAME_LENGTH];
|
||||
|
||||
|
||||
bool observer_check;
|
||||
size_t observer_event_count;
|
||||
char observer_name1[TOX_MAX_NAME_LENGTH];
|
||||
@ -53,7 +52,7 @@ typedef struct State {
|
||||
static bool all_peers_connected(AutoTox *autotoxes)
|
||||
{
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
State *state = (State *)autotoxes[i].state;
|
||||
const State *state = (const State *)autotoxes[i].state;
|
||||
|
||||
if (state->num_peers != NUM_GROUP_TOXES - 1) {
|
||||
return false;
|
||||
@ -146,7 +145,7 @@ static size_t get_state_index_by_nick(const AutoTox *autotoxes, size_t num_peers
|
||||
ck_assert(name != nullptr && name_length <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
for (size_t i = 0; i < num_peers; ++i) {
|
||||
State *state = (State *)autotoxes[i].state;
|
||||
const State *state = (const State *)autotoxes[i].state;
|
||||
|
||||
if (memcmp(state->self_name, name, name_length) == 0) {
|
||||
return i;
|
||||
@ -156,29 +155,33 @@ static size_t get_state_index_by_nick(const AutoTox *autotoxes, size_t num_peers
|
||||
ck_assert_msg(0, "Failed to find index");
|
||||
}
|
||||
|
||||
static void group_join_fail_handler(Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, void *user_data)
|
||||
static void group_join_fail_handler(const Tox_Event_Group_Join_Fail *event, void *user_data)
|
||||
{
|
||||
const Tox_Group_Join_Fail fail_type = tox_event_group_join_fail_get_fail_type(event);
|
||||
fprintf(stderr, "Failed to join group: %d", fail_type);
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t group_number = tox_event_group_peer_join_get_group_number(event);
|
||||
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
|
||||
|
||||
ck_assert(state->group_number == group_number);
|
||||
|
||||
char peer_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
|
||||
Tox_Err_Group_Peer_Query q_err;
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(tox, group_number, peer_id, &q_err);
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, group_number, peer_id, &q_err);
|
||||
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
tox_group_peer_get_name(tox, group_number, peer_id, (uint8_t *) peer_name, &q_err);
|
||||
tox_group_peer_get_name(autotox->tox, group_number, peer_id, (uint8_t *) peer_name, &q_err);
|
||||
peer_name[peer_name_len] = 0;
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
|
||||
@ -193,7 +196,7 @@ static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t pe
|
||||
ck_assert(state->num_peers < NUM_GROUP_TOXES);
|
||||
}
|
||||
|
||||
static void handle_mod(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role)
|
||||
static void handle_mod(State *state, const char *peer_name, size_t peer_name_len)
|
||||
{
|
||||
if (state->mod_event_count == 0) {
|
||||
ck_assert(memcmp(peer_name, state->mod_name1, peer_name_len) == 0);
|
||||
@ -205,10 +208,9 @@ static void handle_mod(State *state, const char *peer_name, size_t peer_name_len
|
||||
|
||||
++state->mod_event_count;
|
||||
state->mod_check = true;
|
||||
ck_assert(role == TOX_GROUP_ROLE_MODERATOR);
|
||||
}
|
||||
|
||||
static void handle_observer(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role)
|
||||
static void handle_observer(State *state, const char *peer_name, size_t peer_name_len)
|
||||
{
|
||||
if (state->observer_event_count == 0) {
|
||||
ck_assert(memcmp(peer_name, state->observer_name1, peer_name_len) == 0);
|
||||
@ -220,10 +222,9 @@ static void handle_observer(State *state, const char *peer_name, size_t peer_nam
|
||||
|
||||
++state->observer_event_count;
|
||||
state->observer_check = true;
|
||||
ck_assert(role == TOX_GROUP_ROLE_OBSERVER);
|
||||
}
|
||||
|
||||
static void handle_user(State *state, const char *peer_name, size_t peer_name_len, Tox_Group_Role role)
|
||||
static void handle_user(State *state, const char *peer_name, size_t peer_name_len)
|
||||
{
|
||||
// event 1: observer1 gets promoted back to user
|
||||
// event 2: observer2 gets promoted to moderator
|
||||
@ -243,23 +244,25 @@ static void handle_user(State *state, const char *peer_name, size_t peer_name_le
|
||||
|
||||
++state->user_event_count;
|
||||
state->user_check = true;
|
||||
ck_assert(role == TOX_GROUP_ROLE_USER);
|
||||
}
|
||||
|
||||
static void group_mod_event_handler(Tox *tox, uint32_t group_number, uint32_t source_peer_id, uint32_t target_peer_id,
|
||||
Tox_Group_Mod_Event mod_type, void *user_data)
|
||||
static void group_mod_event_handler(const Tox_Event_Group_Moderation *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t group_number = tox_event_group_moderation_get_group_number(event);
|
||||
const uint32_t target_peer_id = tox_event_group_moderation_get_target_peer_id(event);
|
||||
const Tox_Group_Mod_Event mod_type = tox_event_group_moderation_get_mod_type(event);
|
||||
|
||||
ck_assert(state->group_number == group_number);
|
||||
|
||||
char peer_name[TOX_MAX_NAME_LENGTH + 1];
|
||||
|
||||
Tox_Err_Group_Peer_Query q_err;
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(tox, group_number, target_peer_id, &q_err);
|
||||
size_t peer_name_len = tox_group_peer_get_name_size(autotox->tox, group_number, target_peer_id, &q_err);
|
||||
|
||||
if (q_err == TOX_ERR_GROUP_PEER_QUERY_PEER_NOT_FOUND) { // may occurr on sync attempts
|
||||
return;
|
||||
@ -268,12 +271,13 @@ static void group_mod_event_handler(Tox *tox, uint32_t group_number, uint32_t so
|
||||
ck_assert_msg(q_err == TOX_ERR_GROUP_PEER_QUERY_OK, "error %d", q_err);
|
||||
ck_assert(peer_name_len <= TOX_MAX_NAME_LENGTH);
|
||||
|
||||
tox_group_peer_get_name(tox, group_number, target_peer_id, (uint8_t *) peer_name, &q_err);
|
||||
tox_group_peer_get_name(autotox->tox, group_number, target_peer_id, (uint8_t *) peer_name, &q_err);
|
||||
peer_name[peer_name_len] = 0;
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
|
||||
Tox_Group_Role role = tox_group_peer_get_role(tox, group_number, target_peer_id, &q_err);
|
||||
Tox_Group_Role role = tox_group_peer_get_role(autotox->tox, group_number, target_peer_id, &q_err);
|
||||
ck_assert(q_err == TOX_ERR_GROUP_PEER_QUERY_OK);
|
||||
ck_assert(role <= TOX_GROUP_ROLE_OBSERVER);
|
||||
|
||||
fprintf(stderr, "tox%u: got moderator event %d (%s), role = %s\n",
|
||||
autotox->index, mod_type, tox_group_mod_event_to_string(mod_type),
|
||||
@ -281,17 +285,17 @@ static void group_mod_event_handler(Tox *tox, uint32_t group_number, uint32_t so
|
||||
|
||||
switch (mod_type) {
|
||||
case TOX_GROUP_MOD_EVENT_MODERATOR: {
|
||||
handle_mod(state, peer_name, peer_name_len, role);
|
||||
handle_mod(state, peer_name, peer_name_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case TOX_GROUP_MOD_EVENT_OBSERVER: {
|
||||
handle_observer(state, peer_name, peer_name_len, role);
|
||||
handle_observer(state, peer_name, peer_name_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case TOX_GROUP_MOD_EVENT_USER: {
|
||||
handle_user(state, peer_name, peer_name_len, role);
|
||||
handle_user(state, peer_name, peer_name_len);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -314,7 +318,7 @@ static void check_self_role(AutoTox *autotoxes, uint32_t peer_id, Tox_Group_Role
|
||||
Tox_Err_Group_Self_Query sq_err;
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
State *state = (State *)autotoxes[i].state;
|
||||
const State *state = (const State *)autotoxes[i].state;
|
||||
|
||||
uint32_t self_peer_id = tox_group_self_get_peer_id(autotoxes[i].tox, state->group_number, &sq_err);
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
@ -378,13 +382,13 @@ static void voice_state_message_test(AutoTox *autotox, Tox_Group_Voice_State voi
|
||||
static bool all_peers_got_voice_state_change(AutoTox *autotoxes, uint32_t num_toxes,
|
||||
Tox_Group_Voice_State expected_voice_state)
|
||||
{
|
||||
Tox_Err_Group_State_Queries query_err;
|
||||
Tox_Err_Group_State_Query query_err;
|
||||
|
||||
for (uint32_t i = 0; i < num_toxes; ++i) {
|
||||
const State *state = (State *)autotoxes[i].state;
|
||||
|
||||
Tox_Group_Voice_State voice_state = tox_group_get_voice_state(autotoxes[i].tox, state->group_number, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
if (voice_state != expected_voice_state) {
|
||||
return false;
|
||||
@ -398,10 +402,10 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes)
|
||||
{
|
||||
// founder sets voice state to Moderator
|
||||
const State *state = (State *)autotoxes[0].state;
|
||||
Tox_Err_Group_Founder_Set_Voice_State voice_set_err;
|
||||
tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_MODERATOR,
|
||||
&voice_set_err);
|
||||
ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK);
|
||||
Tox_Err_Group_Set_Voice_State voice_set_err;
|
||||
tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_MODERATOR,
|
||||
&voice_set_err);
|
||||
ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK);
|
||||
|
||||
for (uint32_t i = 0; i < num_toxes; ++i) {
|
||||
do {
|
||||
@ -411,8 +415,8 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes)
|
||||
voice_state_message_test(&autotoxes[i], TOX_GROUP_VOICE_STATE_MODERATOR);
|
||||
}
|
||||
|
||||
tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_FOUNDER, &voice_set_err);
|
||||
ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK);
|
||||
tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_FOUNDER, &voice_set_err);
|
||||
ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK);
|
||||
|
||||
for (uint32_t i = 0; i < num_toxes; ++i) {
|
||||
do {
|
||||
@ -422,8 +426,8 @@ static void check_voice_state(AutoTox *autotoxes, uint32_t num_toxes)
|
||||
voice_state_message_test(&autotoxes[i], TOX_GROUP_VOICE_STATE_FOUNDER);
|
||||
}
|
||||
|
||||
tox_group_founder_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_ALL, &voice_set_err);
|
||||
ck_assert(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK);
|
||||
tox_group_set_voice_state(autotoxes[0].tox, state->group_number, TOX_GROUP_VOICE_STATE_ALL, &voice_set_err);
|
||||
ck_assert(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK);
|
||||
|
||||
for (uint32_t i = 0; i < num_toxes; ++i) {
|
||||
do {
|
||||
@ -447,9 +451,9 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
snprintf(state->self_name, sizeof(state->self_name), "peer_%zu", i);
|
||||
state->self_name[name_length] = 0;
|
||||
|
||||
tox_callback_group_join_fail(autotoxes[i].tox, group_join_fail_handler);
|
||||
tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
|
||||
tox_callback_group_moderation(autotoxes[i].tox, group_mod_event_handler);
|
||||
tox_events_callback_group_join_fail(autotoxes[i].dispatch, group_join_fail_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_moderation(autotoxes[i].dispatch, group_mod_event_handler);
|
||||
}
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
@ -468,11 +472,11 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
ck_assert_msg(err_new == TOX_ERR_GROUP_NEW_OK, "Failed to create group. error: %d\n", err_new);
|
||||
|
||||
/* Founder gets chat ID */
|
||||
Tox_Err_Group_State_Queries id_err;
|
||||
Tox_Err_Group_State_Query id_err;
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
tox_group_get_chat_id(tox0, state0->group_number, chat_id, &id_err);
|
||||
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get chat ID. error: %d", id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get chat ID. error: %d", id_err);
|
||||
|
||||
fprintf(stderr, "Peers attemping to join DHT group via the chat ID\n");
|
||||
|
||||
@ -512,7 +516,7 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
|
||||
/* all peers should be user role except founder */
|
||||
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {
|
||||
State *state = (State *)autotoxes[i].state;
|
||||
const State *state = (const State *)autotoxes[i].state;
|
||||
self_role = tox_group_self_get_role(autotoxes[i].tox, state->group_number, &sq_err);
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
ck_assert(self_role == TOX_GROUP_ROLE_USER);
|
||||
@ -521,9 +525,9 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
/* founder sets first peer to moderator */
|
||||
fprintf(stderr, "Founder setting %s to moderator\n", state0->peers[0].name);
|
||||
|
||||
Tox_Err_Group_Mod_Set_Role role_err;
|
||||
tox_group_mod_set_role(tox0, state0->group_number, state0->peers[0].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
|
||||
Tox_Err_Group_Set_Role role_err;
|
||||
tox_group_set_role(tox0, state0->group_number, state0->peers[0].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
|
||||
|
||||
// manually flag the role setter because they don't get a callback
|
||||
state0->mod_check = true;
|
||||
@ -537,8 +541,8 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
/* founder sets second and third peer to observer */
|
||||
fprintf(stderr, "Founder setting %s to observer\n", state0->peers[1].name);
|
||||
|
||||
tox_group_mod_set_role(tox0, state0->group_number, state0->peers[1].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set observer. error: %d", role_err);
|
||||
tox_group_set_role(tox0, state0->group_number, state0->peers[1].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set observer. error: %d", role_err);
|
||||
|
||||
state0->observer_check = true;
|
||||
++state0->observer_event_count;
|
||||
@ -548,8 +552,8 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
|
||||
fprintf(stderr, "Founder setting %s to observer\n", state0->peers[2].name);
|
||||
|
||||
tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set observer. error: %d", role_err);
|
||||
tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set observer. error: %d", role_err);
|
||||
|
||||
state0->observer_check = true;
|
||||
++state0->observer_event_count;
|
||||
@ -574,8 +578,8 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
|
||||
fprintf(stderr, "%s is promoting %s back to user\n", state1->self_name, state0->peers[1].name);
|
||||
|
||||
tox_group_mod_set_role(tox1, state1->group_number, obs_peer_id, TOX_GROUP_ROLE_USER, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to promote observer back to user. error: %d",
|
||||
tox_group_set_role(tox1, state1->group_number, obs_peer_id, TOX_GROUP_ROLE_USER, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to promote observer back to user. error: %d",
|
||||
role_err);
|
||||
|
||||
state1->user_check = true;
|
||||
@ -587,8 +591,8 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
/* founder assigns third peer to moderator (this triggers two events: user and moderator) */
|
||||
fprintf(stderr, "Founder setting %s to moderator\n", state0->peers[2].name);
|
||||
|
||||
tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
|
||||
tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_MODERATOR, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
|
||||
|
||||
state0->mod_check = true;
|
||||
++state0->mod_event_count;
|
||||
@ -600,18 +604,27 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
|
||||
/* moderator attempts to demote and kick founder */
|
||||
uint32_t founder_peer_id = get_peer_id_by_nick(state1->peers, NUM_GROUP_TOXES - 1, state0->self_name);
|
||||
tox_group_mod_set_role(tox1, state1->group_number, founder_peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
|
||||
ck_assert_msg(role_err != TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Mod set founder to observer");
|
||||
tox_group_set_role(tox1, state1->group_number, founder_peer_id, TOX_GROUP_ROLE_OBSERVER, &role_err);
|
||||
ck_assert_msg(role_err != TOX_ERR_GROUP_SET_ROLE_OK, "Mod set founder to observer");
|
||||
|
||||
Tox_Err_Group_Mod_Kick_Peer k_err;
|
||||
tox_group_mod_kick_peer(tox1, state1->group_number, founder_peer_id, &k_err);
|
||||
ck_assert_msg(k_err != TOX_ERR_GROUP_MOD_KICK_PEER_OK, "Mod kicked founder");
|
||||
Tox_Err_Group_Kick_Peer k_err;
|
||||
tox_group_kick_peer(tox1, state1->group_number, founder_peer_id, &k_err);
|
||||
ck_assert_msg(k_err != TOX_ERR_GROUP_KICK_PEER_OK, "Mod kicked founder");
|
||||
|
||||
/* the moderator about to be kicked changes the topic to trigger the founder to
|
||||
* re-sign and redistribute it after the kick.
|
||||
*/
|
||||
const State *state_x = (const State *)autotoxes[idx].state;
|
||||
Tox *tox_x = autotoxes[idx].tox;
|
||||
Tox_Err_Group_Topic_Set topic_err;
|
||||
tox_group_set_topic(tox_x, state_x->group_number, nullptr, 0, &topic_err);
|
||||
ck_assert(topic_err == TOX_ERR_GROUP_TOPIC_SET_OK);
|
||||
|
||||
/* founder kicks moderator (this triggers two events: user and kick) */
|
||||
fprintf(stderr, "Founder is kicking %s\n", state0->peers[0].name);
|
||||
|
||||
tox_group_mod_kick_peer(tox0, state0->group_number, state0->peers[0].peer_id, &k_err);
|
||||
ck_assert_msg(k_err == TOX_ERR_GROUP_MOD_KICK_PEER_OK, "Failed to kick peer. error: %d", k_err);
|
||||
tox_group_kick_peer(tox0, state0->group_number, state0->peers[0].peer_id, &k_err);
|
||||
ck_assert_msg(k_err == TOX_ERR_GROUP_KICK_PEER_OK, "Failed to kick peer. error: %d", k_err);
|
||||
|
||||
state0->kick_check = true;
|
||||
check_mod_event(autotoxes, NUM_GROUP_TOXES, TOX_GROUP_MOD_EVENT_KICK);
|
||||
@ -619,9 +632,8 @@ static void group_moderation_test(AutoTox *autotoxes)
|
||||
fprintf(stderr, "All peers successfully received kick event\n");
|
||||
|
||||
fprintf(stderr, "Founder is demoting moderator to user\n");
|
||||
|
||||
tox_group_mod_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_USER, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to demote peer 3 to User. error: %d", role_err);
|
||||
tox_group_set_role(tox0, state0->group_number, state0->peers[2].peer_id, TOX_GROUP_ROLE_USER, &role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to demote peer 3 to User. error: %d", role_err);
|
||||
|
||||
state0->user_check = true;
|
||||
++state0->user_event_count;
|
||||
|
@ -26,17 +26,23 @@ typedef struct State {
|
||||
#define PEER0_NICK_LEN (sizeof(PEER0_NICK) -1)
|
||||
#define NEW_USER_STATUS TOX_USER_STATUS_BUSY
|
||||
|
||||
static void group_invite_handler(Tox *tox, 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)
|
||||
static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
const uint32_t friend_number = tox_event_group_invite_get_friend_number(event);
|
||||
const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event);
|
||||
const size_t length = tox_event_group_invite_get_invite_data_length(event);
|
||||
|
||||
Tox_Err_Group_Invite_Accept err_accept;
|
||||
tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)"test2", 5,
|
||||
tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)"test2", 5,
|
||||
nullptr, 0, &err_accept);
|
||||
ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK);
|
||||
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
@ -52,28 +58,28 @@ static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t pe
|
||||
*/
|
||||
static int has_correct_group_state(const Tox *tox, uint32_t group_number, const uint8_t *expected_chat_id)
|
||||
{
|
||||
Tox_Err_Group_State_Queries query_err;
|
||||
Tox_Err_Group_State_Query query_err;
|
||||
|
||||
Tox_Group_Privacy_State priv_state = tox_group_get_privacy_state(tox, group_number, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
if (priv_state != NEW_PRIV_STATE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t pass_len = tox_group_get_password_size(tox, group_number, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
uint8_t password[TOX_GROUP_MAX_PASSWORD_SIZE];
|
||||
tox_group_get_password(tox, group_number, password, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
if (pass_len != PASS_LEN || memcmp(password, PASSWORD, pass_len) != 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
size_t gname_len = tox_group_get_name_size(tox, group_number, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
uint8_t group_name[TOX_GROUP_MAX_GROUP_NAME_LENGTH];
|
||||
tox_group_get_name(tox, group_number, group_name, &query_err);
|
||||
@ -87,17 +93,17 @@ static int has_correct_group_state(const Tox *tox, uint32_t group_number, const
|
||||
}
|
||||
|
||||
Tox_Group_Topic_Lock topic_lock = tox_group_get_topic_lock(tox, group_number, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
if (topic_lock != TOX_GROUP_TOPIC_LOCK_DISABLED) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
Tox_Err_Group_State_Queries id_err;
|
||||
Tox_Err_Group_State_Query id_err;
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
tox_group_get_chat_id(tox, group_number, chat_id, &id_err);
|
||||
|
||||
ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
if (memcmp(chat_id, expected_chat_id, TOX_GROUP_CHAT_ID_SIZE) != 0) {
|
||||
return -6;
|
||||
@ -120,7 +126,7 @@ static int has_correct_self_state(const Tox *tox, uint32_t group_number, const u
|
||||
return -1;
|
||||
}
|
||||
|
||||
TOX_USER_STATUS self_status = tox_group_self_get_status(tox, group_number, &sq_err);
|
||||
Tox_User_Status self_status = tox_group_self_get_status(tox, group_number, &sq_err);
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
|
||||
if (self_status != NEW_USER_STATUS) {
|
||||
@ -151,8 +157,8 @@ static void group_save_test(AutoTox *autotoxes)
|
||||
ck_assert_msg(NUM_GROUP_TOXES > 1, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
tox_callback_group_invite(autotoxes[i].tox, group_invite_handler);
|
||||
tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
|
||||
tox_events_callback_group_invite(autotoxes[i].dispatch, group_invite_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler);
|
||||
}
|
||||
|
||||
Tox *tox0 = autotoxes[0].tox;
|
||||
@ -168,9 +174,9 @@ static void group_save_test(AutoTox *autotoxes)
|
||||
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
|
||||
Tox_Err_Group_State_Queries id_err;
|
||||
Tox_Err_Group_State_Query id_err;
|
||||
tox_group_get_chat_id(tox0, group_number, chat_id, &id_err);
|
||||
ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(id_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
uint8_t founder_pk[TOX_GROUP_PEER_PUBLIC_KEY_SIZE];
|
||||
|
||||
@ -178,7 +184,6 @@ static void group_save_test(AutoTox *autotoxes)
|
||||
tox_group_self_get_public_key(tox0, group_number, founder_pk, &sq_err);
|
||||
ck_assert(sq_err == TOX_ERR_GROUP_SELF_QUERY_OK);
|
||||
|
||||
|
||||
Tox_Err_Group_Invite_Friend err_invite;
|
||||
tox_group_invite_friend(tox0, group_number, 0, &err_invite);
|
||||
|
||||
@ -195,21 +200,21 @@ static void group_save_test(AutoTox *autotoxes)
|
||||
tox_group_set_topic(tox0, group_number, (const uint8_t *)TOPIC, TOPIC_LEN, &top_err);
|
||||
ck_assert(top_err == TOX_ERR_GROUP_TOPIC_SET_OK);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err;
|
||||
tox_group_founder_set_topic_lock(tox0, group_number, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
|
||||
ck_assert(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK);
|
||||
Tox_Err_Group_Set_Topic_Lock lock_set_err;
|
||||
tox_group_set_topic_lock(tox0, group_number, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
|
||||
ck_assert(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Privacy_State priv_err;
|
||||
tox_group_founder_set_privacy_state(tox0, group_number, NEW_PRIV_STATE, &priv_err);
|
||||
ck_assert(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK);
|
||||
Tox_Err_Group_Set_Privacy_State priv_err;
|
||||
tox_group_set_privacy_state(tox0, group_number, NEW_PRIV_STATE, &priv_err);
|
||||
ck_assert(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Password pass_set_err;
|
||||
tox_group_founder_set_password(tox0, group_number, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err);
|
||||
ck_assert(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK);
|
||||
Tox_Err_Group_Set_Password pass_set_err;
|
||||
tox_group_set_password(tox0, group_number, (const uint8_t *)PASSWORD, PASS_LEN, &pass_set_err);
|
||||
ck_assert(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err;
|
||||
tox_group_founder_set_peer_limit(tox0, group_number, PEER_LIMIT, &limit_set_err);
|
||||
ck_assert(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK);
|
||||
Tox_Err_Group_Set_Peer_Limit limit_set_err;
|
||||
tox_group_set_peer_limit(tox0, group_number, PEER_LIMIT, &limit_set_err);
|
||||
ck_assert(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK);
|
||||
|
||||
// change self state
|
||||
Tox_Err_Group_Self_Name_Set n_err;
|
||||
@ -241,8 +246,8 @@ static void group_save_test(AutoTox *autotoxes)
|
||||
ck_assert(options != nullptr);
|
||||
|
||||
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
||||
|
||||
tox_options_set_savedata_data(options, save, save_length);
|
||||
tox_options_set_experimental_groups_persistence(options, true);
|
||||
|
||||
Tox *new_tox = tox_new_log(options, nullptr, nullptr);
|
||||
|
||||
@ -278,7 +283,11 @@ int main(void)
|
||||
Run_Auto_Options autotest_opts = default_run_auto_options();
|
||||
autotest_opts.graph = GRAPH_COMPLETE;
|
||||
|
||||
run_auto_test(nullptr, NUM_GROUP_TOXES, group_save_test, sizeof(State), &autotest_opts);
|
||||
Tox_Options *opts = tox_options_new(nullptr);
|
||||
ck_assert(opts != nullptr);
|
||||
tox_options_set_experimental_groups_persistence(opts, true);
|
||||
run_auto_test(opts, NUM_GROUP_TOXES, group_save_test, sizeof(State), &autotest_opts);
|
||||
tox_options_free(opts);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -60,66 +60,97 @@ static bool all_group_peers_connected(const AutoTox *autotoxes, uint32_t tox_cou
|
||||
return true;
|
||||
}
|
||||
|
||||
static void group_topic_lock_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock,
|
||||
static void group_topic_lock_handler(const Tox_Event_Group_Topic_Lock *event,
|
||||
void *user_data)
|
||||
{
|
||||
Tox_Err_Group_State_Queries err;
|
||||
Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(tox, groupnumber, &err);
|
||||
const AutoTox *autotox = (const AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
const uint32_t groupnumber = tox_event_group_topic_lock_get_group_number(event);
|
||||
const Tox_Group_Topic_Lock topic_lock = tox_event_group_topic_lock_get_topic_lock(event);
|
||||
|
||||
Tox_Err_Group_State_Query err;
|
||||
Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(autotox->tox, groupnumber, &err);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
ck_assert_msg(current_topic_lock == topic_lock, "topic locks don't match in callback: %d %d",
|
||||
topic_lock, current_topic_lock);
|
||||
}
|
||||
|
||||
static void group_voice_state_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Voice_State voice_state,
|
||||
static void group_voice_state_handler(const Tox_Event_Group_Voice_State *event,
|
||||
void *user_data)
|
||||
{
|
||||
Tox_Err_Group_State_Queries err;
|
||||
Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(tox, groupnumber, &err);
|
||||
const AutoTox *autotox = (const AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
const uint32_t groupnumber = tox_event_group_voice_state_get_group_number(event);
|
||||
const Tox_Group_Voice_State voice_state = tox_event_group_voice_state_get_voice_state(event);
|
||||
|
||||
Tox_Err_Group_State_Query err;
|
||||
Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(autotox->tox, groupnumber, &err);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
ck_assert_msg(current_voice_state == voice_state, "voice states don't match in callback: %d %d",
|
||||
voice_state, current_voice_state);
|
||||
}
|
||||
|
||||
static void group_privacy_state_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Privacy_State privacy_state,
|
||||
static void group_privacy_state_handler(const Tox_Event_Group_Privacy_State *event,
|
||||
void *user_data)
|
||||
{
|
||||
Tox_Err_Group_State_Queries err;
|
||||
Tox_Group_Privacy_State current_pstate = tox_group_get_privacy_state(tox, groupnumber, &err);
|
||||
const AutoTox *autotox = (const AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
const uint32_t groupnumber = tox_event_group_privacy_state_get_group_number(event);
|
||||
const Tox_Group_Privacy_State privacy_state = tox_event_group_privacy_state_get_privacy_state(event);
|
||||
|
||||
Tox_Err_Group_State_Query err;
|
||||
Tox_Group_Privacy_State current_pstate = tox_group_get_privacy_state(autotox->tox, groupnumber, &err);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
ck_assert_msg(current_pstate == privacy_state, "privacy states don't match in callback");
|
||||
}
|
||||
|
||||
static void group_peer_limit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_limit, void *user_data)
|
||||
static void group_peer_limit_handler(const Tox_Event_Group_Peer_Limit *event, void *user_data)
|
||||
{
|
||||
Tox_Err_Group_State_Queries err;
|
||||
uint32_t current_plimit = tox_group_get_peer_limit(tox, groupnumber, &err);
|
||||
const AutoTox *autotox = (const AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
const uint32_t groupnumber = tox_event_group_peer_limit_get_group_number(event);
|
||||
const uint32_t peer_limit = tox_event_group_peer_limit_get_peer_limit(event);
|
||||
|
||||
Tox_Err_Group_State_Query err;
|
||||
uint32_t current_plimit = tox_group_get_peer_limit(autotox->tox, groupnumber, &err);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
ck_assert_msg(peer_limit == current_plimit,
|
||||
"Peer limits don't match in callback: %u, %u\n", peer_limit, current_plimit);
|
||||
}
|
||||
|
||||
static void group_password_handler(Tox *tox, uint32_t groupnumber, const uint8_t *password, size_t length,
|
||||
static void group_password_handler(const Tox_Event_Group_Password *event,
|
||||
void *user_data)
|
||||
{
|
||||
Tox_Err_Group_State_Queries err;
|
||||
size_t curr_pwlength = tox_group_get_password_size(tox, groupnumber, &err);
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
const uint32_t groupnumber = tox_event_group_password_get_group_number(event);
|
||||
const uint8_t *password = tox_event_group_password_get_password(event);
|
||||
const size_t length = tox_event_group_password_get_password_length(event);
|
||||
|
||||
Tox_Err_Group_State_Query err;
|
||||
size_t curr_pwlength = tox_group_get_password_size(autotox->tox, groupnumber, &err);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
ck_assert(length == curr_pwlength);
|
||||
|
||||
uint8_t current_password[TOX_GROUP_MAX_PASSWORD_SIZE];
|
||||
tox_group_get_password(tox, groupnumber, current_password, &err);
|
||||
tox_group_get_password(autotox->tox, groupnumber, current_password, &err);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
ck_assert_msg(memcmp(current_password, password, length) == 0,
|
||||
"Passwords don't match: %s, %s", password, current_password);
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
@ -137,24 +168,24 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
|
||||
Tox_Group_Privacy_State priv_state, Tox_Group_Voice_State voice_state,
|
||||
const uint8_t *password, size_t pass_len, Tox_Group_Topic_Lock topic_lock)
|
||||
{
|
||||
Tox_Err_Group_State_Queries query_err;
|
||||
Tox_Err_Group_State_Query query_err;
|
||||
|
||||
Tox_Group_Privacy_State my_priv_state = tox_group_get_privacy_state(tox, groupnumber, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get privacy state: %d", query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get privacy state: %d", query_err);
|
||||
|
||||
if (my_priv_state != priv_state) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t my_peer_limit = tox_group_get_peer_limit(tox, groupnumber, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get peer limit: %d", query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get peer limit: %d", query_err);
|
||||
|
||||
if (my_peer_limit != peer_limit) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
size_t my_pass_len = tox_group_get_password_size(tox, groupnumber, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get password size: %d", query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get password size: %d", query_err);
|
||||
|
||||
if (my_pass_len != pass_len) {
|
||||
return -5;
|
||||
@ -163,10 +194,10 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
|
||||
if (password != nullptr && my_pass_len > 0) {
|
||||
ck_assert(my_pass_len <= TOX_GROUP_MAX_PASSWORD_SIZE);
|
||||
|
||||
uint8_t my_pass[TOX_GROUP_MAX_PASSWORD_SIZE];
|
||||
uint8_t my_pass[TOX_GROUP_MAX_PASSWORD_SIZE + 1];
|
||||
tox_group_get_password(tox, groupnumber, my_pass, &query_err);
|
||||
my_pass[my_pass_len] = 0;
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get password: %d", query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get password: %d", query_err);
|
||||
|
||||
if (memcmp(my_pass, password, my_pass_len) != 0) {
|
||||
return -6;
|
||||
@ -175,7 +206,7 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
|
||||
|
||||
/* Group name should never change */
|
||||
size_t my_gname_len = tox_group_get_name_size(tox, groupnumber, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get group name size: %d", query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get group name size: %d", query_err);
|
||||
|
||||
if (my_gname_len != GROUP_NAME_LEN) {
|
||||
return -7;
|
||||
@ -183,7 +214,7 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
|
||||
|
||||
ck_assert(my_gname_len <= TOX_GROUP_MAX_GROUP_NAME_LENGTH);
|
||||
|
||||
uint8_t my_gname[TOX_GROUP_MAX_GROUP_NAME_LENGTH];
|
||||
uint8_t my_gname[TOX_GROUP_MAX_GROUP_NAME_LENGTH + 1];
|
||||
tox_group_get_name(tox, groupnumber, my_gname, &query_err);
|
||||
my_gname[my_gname_len] = 0;
|
||||
|
||||
@ -192,14 +223,14 @@ static int check_group_state(const Tox *tox, uint32_t groupnumber, uint32_t peer
|
||||
}
|
||||
|
||||
Tox_Group_Topic_Lock current_topic_lock = tox_group_get_topic_lock(tox, groupnumber, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get topic lock: %d", query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get topic lock: %d", query_err);
|
||||
|
||||
if (current_topic_lock != topic_lock) {
|
||||
return -9;
|
||||
}
|
||||
|
||||
Tox_Group_Voice_State current_voice_state = tox_group_get_voice_state(tox, groupnumber, &query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "Failed to get voice state: %d", query_err);
|
||||
ck_assert_msg(query_err == TOX_ERR_GROUP_STATE_QUERY_OK, "Failed to get voice state: %d", query_err);
|
||||
|
||||
if (current_voice_state != voice_state) {
|
||||
return -10;
|
||||
@ -213,26 +244,26 @@ static void set_group_state(Tox *tox, uint32_t groupnumber, uint32_t peer_limit,
|
||||
Tox_Group_Topic_Lock topic_lock)
|
||||
{
|
||||
|
||||
Tox_Err_Group_Founder_Set_Peer_Limit limit_set_err;
|
||||
tox_group_founder_set_peer_limit(tox, groupnumber, peer_limit, &limit_set_err);
|
||||
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_FOUNDER_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err);
|
||||
Tox_Err_Group_Set_Peer_Limit limit_set_err;
|
||||
tox_group_set_peer_limit(tox, groupnumber, peer_limit, &limit_set_err);
|
||||
ck_assert_msg(limit_set_err == TOX_ERR_GROUP_SET_PEER_LIMIT_OK, "failed to set peer limit: %d", limit_set_err);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Privacy_State priv_err;
|
||||
tox_group_founder_set_privacy_state(tox, groupnumber, priv_state, &priv_err);
|
||||
ck_assert_msg(priv_err == TOX_ERR_GROUP_FOUNDER_SET_PRIVACY_STATE_OK, "failed to set privacy state: %d", priv_err);
|
||||
Tox_Err_Group_Set_Privacy_State priv_err;
|
||||
tox_group_set_privacy_state(tox, groupnumber, priv_state, &priv_err);
|
||||
ck_assert_msg(priv_err == TOX_ERR_GROUP_SET_PRIVACY_STATE_OK, "failed to set privacy state: %d", priv_err);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Password pass_set_err;
|
||||
tox_group_founder_set_password(tox, groupnumber, password, pass_len, &pass_set_err);
|
||||
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_FOUNDER_SET_PASSWORD_OK, "failed to set password: %d", pass_set_err);
|
||||
Tox_Err_Group_Set_Password pass_set_err;
|
||||
tox_group_set_password(tox, groupnumber, password, pass_len, &pass_set_err);
|
||||
ck_assert_msg(pass_set_err == TOX_ERR_GROUP_SET_PASSWORD_OK, "failed to set password: %d", pass_set_err);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err;
|
||||
tox_group_founder_set_topic_lock(tox, groupnumber, topic_lock, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to set topic lock: %d",
|
||||
Tox_Err_Group_Set_Topic_Lock lock_set_err;
|
||||
tox_group_set_topic_lock(tox, groupnumber, topic_lock, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to set topic lock: %d",
|
||||
lock_set_err);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Voice_State voice_set_err;
|
||||
tox_group_founder_set_voice_state(tox, groupnumber, voice_state, &voice_set_err);
|
||||
ck_assert_msg(voice_set_err == TOX_ERR_GROUP_FOUNDER_SET_VOICE_STATE_OK, "failed to set voice state: %d",
|
||||
Tox_Err_Group_Set_Voice_State voice_set_err;
|
||||
tox_group_set_voice_state(tox, groupnumber, voice_state, &voice_set_err);
|
||||
ck_assert_msg(voice_set_err == TOX_ERR_GROUP_SET_VOICE_STATE_OK, "failed to set voice state: %d",
|
||||
voice_set_err);
|
||||
}
|
||||
|
||||
@ -241,12 +272,12 @@ static void group_state_test(AutoTox *autotoxes)
|
||||
ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
tox_callback_group_privacy_state(autotoxes[i].tox, group_privacy_state_handler);
|
||||
tox_callback_group_peer_limit(autotoxes[i].tox, group_peer_limit_handler);
|
||||
tox_callback_group_password(autotoxes[i].tox, group_password_handler);
|
||||
tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
|
||||
tox_callback_group_voice_state(autotoxes[i].tox, group_voice_state_handler);
|
||||
tox_callback_group_topic_lock(autotoxes[i].tox, group_topic_lock_handler);
|
||||
tox_events_callback_group_privacy_state(autotoxes[i].dispatch, group_privacy_state_handler);
|
||||
tox_events_callback_group_peer_limit(autotoxes[i].dispatch, group_peer_limit_handler);
|
||||
tox_events_callback_group_password(autotoxes[i].dispatch, group_password_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_voice_state(autotoxes[i].dispatch, group_voice_state_handler);
|
||||
tox_events_callback_group_topic_lock(autotoxes[i].dispatch, group_topic_lock_handler);
|
||||
}
|
||||
|
||||
Tox *tox0 = autotoxes[0].tox;
|
||||
@ -263,11 +294,11 @@ static void group_state_test(AutoTox *autotoxes)
|
||||
(const uint8_t *)PASSWORD, PASS_LEN, TOX_GROUP_TOPIC_LOCK_ENABLED);
|
||||
|
||||
/* Founder gets the Chat ID and implicitly shares it publicly */
|
||||
Tox_Err_Group_State_Queries id_err;
|
||||
Tox_Err_Group_State_Query id_err;
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
tox_group_get_chat_id(tox0, groupnum, chat_id, &id_err);
|
||||
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "tox_group_get_chat_id failed %d", id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "tox_group_get_chat_id failed %d", id_err);
|
||||
|
||||
/* All other peers join the group using the Chat ID and password */
|
||||
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {
|
||||
|
@ -96,38 +96,42 @@ static void peers_cleanup(Peers *peers)
|
||||
free(peers);
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t group_number, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
|
||||
|
||||
ck_assert(add_peer(state->peers, peer_id) == 0);
|
||||
|
||||
}
|
||||
|
||||
static void group_peer_exit_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, Tox_Group_Exit_Type exit_type,
|
||||
const uint8_t *name, size_t name_length, const uint8_t *part_message,
|
||||
size_t length, void *user_data)
|
||||
static void group_peer_exit_handler(const Tox_Event_Group_Peer_Exit *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t peer_id = tox_event_group_peer_exit_get_peer_id(event);
|
||||
|
||||
ck_assert(del_peer(state->peers, peer_id) == 0);
|
||||
|
||||
}
|
||||
|
||||
static void group_topic_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *topic,
|
||||
size_t length, void *user_data)
|
||||
static void group_topic_handler(const Tox_Event_Group_Topic *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint8_t *topic = tox_event_group_topic_get_topic(event);
|
||||
const size_t length = tox_event_group_topic_get_topic_length(event);
|
||||
|
||||
ck_assert(length <= TOX_GROUP_MAX_TOPIC_LENGTH);
|
||||
|
||||
memcpy(state->callback_topic, (const char *)topic, length);
|
||||
@ -201,7 +205,7 @@ static void role_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers,
|
||||
int64_t peer_id = state0->peers->peer_ids[idx];
|
||||
|
||||
if (peer_id >= 0) {
|
||||
tox_group_mod_set_role(tox0, groupnumber, (uint32_t)peer_id, f_role, nullptr);
|
||||
tox_group_set_role(tox0, groupnumber, (uint32_t)peer_id, f_role, nullptr);
|
||||
}
|
||||
|
||||
// mods randomly promote or demote one of the non-mods
|
||||
@ -218,7 +222,7 @@ static void role_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers,
|
||||
peer_id = state_j->peers->peer_ids[i];
|
||||
|
||||
if (peer_id >= 0) {
|
||||
tox_group_mod_set_role(autotoxes[j].tox, groupnumber, (uint32_t)peer_id, role, nullptr);
|
||||
tox_group_set_role(autotoxes[j].tox, groupnumber, (uint32_t)peer_id, role, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -260,14 +264,14 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee
|
||||
{
|
||||
uint8_t expected_topic[TOX_GROUP_MAX_TOPIC_LENGTH];
|
||||
|
||||
Tox_Err_Group_State_Queries query_err;
|
||||
Tox_Err_Group_State_Query query_err;
|
||||
size_t expected_topic_length = tox_group_get_topic_size(autotoxes[0].tox, groupnumber, &query_err);
|
||||
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
tox_group_get_topic(autotoxes[0].tox, groupnumber, expected_topic, &query_err);
|
||||
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
const State *state0 = (const State *)autotoxes[0].state;
|
||||
|
||||
@ -282,7 +286,7 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee
|
||||
for (size_t i = 1; i < num_peers; ++i) {
|
||||
size_t topic_length = tox_group_get_topic_size(autotoxes[i].tox, groupnumber, &query_err);
|
||||
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
if (topic_length != expected_topic_length) {
|
||||
return false;
|
||||
@ -291,7 +295,7 @@ static bool all_peers_have_same_topic(const AutoTox *autotoxes, uint32_t num_pee
|
||||
uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH];
|
||||
tox_group_get_topic(autotoxes[i].tox, groupnumber, topic, &query_err);
|
||||
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
if (memcmp(expected_topic, (const char *)topic, topic_length) != 0) {
|
||||
return false;
|
||||
@ -331,13 +335,13 @@ static void topic_spam(const Random *rng, AutoTox *autotoxes, uint32_t num_peers
|
||||
static void group_sync_test(AutoTox *autotoxes)
|
||||
{
|
||||
ck_assert(NUM_GROUP_TOXES >= 5);
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
|
||||
tox_callback_group_topic(autotoxes[i].tox, group_topic_handler);
|
||||
tox_callback_group_peer_exit(autotoxes[i].tox, group_peer_exit_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_topic(autotoxes[i].dispatch, group_topic_handler);
|
||||
tox_events_callback_group_peer_exit(autotoxes[i].dispatch, group_peer_exit_handler);
|
||||
|
||||
State *state = (State *)autotoxes[i].state;
|
||||
state->peers = (Peers *)calloc(1, sizeof(Peers));
|
||||
@ -356,11 +360,11 @@ static void group_sync_test(AutoTox *autotoxes)
|
||||
|
||||
fprintf(stderr, "tox0 creats new group and invites all his friends");
|
||||
|
||||
Tox_Err_Group_State_Queries id_err;
|
||||
Tox_Err_Group_State_Query id_err;
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
|
||||
tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err);
|
||||
|
||||
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {
|
||||
Tox_Err_Group_Join join_err;
|
||||
@ -375,9 +379,9 @@ static void group_sync_test(AutoTox *autotoxes)
|
||||
|
||||
fprintf(stderr, "%d peers joined the group\n", NUM_GROUP_TOXES);
|
||||
|
||||
Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err;
|
||||
tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d",
|
||||
Tox_Err_Group_Set_Topic_Lock lock_set_err;
|
||||
tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d",
|
||||
lock_set_err);
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
@ -388,8 +392,8 @@ static void group_sync_test(AutoTox *autotoxes)
|
||||
|
||||
iterate_all_wait(autotoxes, NUM_GROUP_TOXES, ITERATION_INTERVAL);
|
||||
|
||||
tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d",
|
||||
tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d",
|
||||
lock_set_err);
|
||||
|
||||
do {
|
||||
@ -398,12 +402,12 @@ static void group_sync_test(AutoTox *autotoxes)
|
||||
&& !all_peers_see_same_roles(autotoxes, NUM_GROUP_TOXES, groupnumber)
|
||||
&& state0->peers->num_peers != NUM_GROUP_TOXES - 1);
|
||||
|
||||
Tox_Err_Group_Mod_Set_Role role_err;
|
||||
Tox_Err_Group_Set_Role role_err;
|
||||
|
||||
for (size_t i = 0; i < state0->peers->num_peers; ++i) {
|
||||
tox_group_mod_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_MODERATOR,
|
||||
&role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
|
||||
tox_group_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_MODERATOR,
|
||||
&role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set moderator. error: %d", role_err);
|
||||
}
|
||||
|
||||
fprintf(stderr, "founder enabled topic lock and set all peers to moderator role\n");
|
||||
@ -419,9 +423,9 @@ static void group_sync_test(AutoTox *autotoxes)
|
||||
fprintf(stderr, "founder demoting %u moderators to user\n", num_demoted);
|
||||
|
||||
for (size_t i = 0; i < num_demoted; ++i) {
|
||||
tox_group_mod_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_USER,
|
||||
&role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set user. error: %d", role_err);
|
||||
tox_group_set_role(tox0, groupnumber, (uint32_t)state0->peers->peer_ids[i], TOX_GROUP_ROLE_USER,
|
||||
&role_err);
|
||||
ck_assert_msg(role_err == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set user. error: %d", role_err);
|
||||
}
|
||||
|
||||
do {
|
||||
|
@ -19,32 +19,43 @@ typedef struct State {
|
||||
uint32_t peer_id[NUM_GROUP_TOXES - 1];
|
||||
} State;
|
||||
|
||||
static void group_invite_handler(Tox *tox, 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)
|
||||
static void group_invite_handler(const Tox_Event_Group_Invite *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
const uint32_t friend_number = tox_event_group_invite_get_friend_number(event);
|
||||
const uint8_t *invite_data = tox_event_group_invite_get_invite_data(event);
|
||||
const size_t length = tox_event_group_invite_get_invite_data_length(event);
|
||||
|
||||
printf("Accepting friend invite\n");
|
||||
|
||||
Tox_Err_Group_Invite_Accept err_accept;
|
||||
tox_group_invite_accept(tox, friend_number, invite_data, length, (const uint8_t *)"test", 4,
|
||||
tox_group_invite_accept(autotox->tox, friend_number, invite_data, length, (const uint8_t *)"test", 4,
|
||||
nullptr, 0, &err_accept);
|
||||
ck_assert(err_accept == TOX_ERR_GROUP_INVITE_ACCEPT_OK);
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
|
||||
|
||||
fprintf(stderr, "joined: %zu, %u\n", state->num_peers, peer_id);
|
||||
ck_assert_msg(state->num_peers < NUM_GROUP_TOXES - 1, "%zu", state->num_peers);
|
||||
|
||||
state->peer_id[state->num_peers++] = peer_id;
|
||||
}
|
||||
|
||||
static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
|
||||
const uint8_t *message, size_t length, void *user_data)
|
||||
static void group_private_message_handler(const Tox_Event_Group_Private_Message *event, void *user_data)
|
||||
{
|
||||
const uint8_t *message = tox_event_group_private_message_get_message(event);
|
||||
const size_t length = tox_event_group_private_message_get_message_length(event);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
@ -58,9 +69,11 @@ static void group_private_message_handler(Tox *tox, uint32_t groupnumber, uint32
|
||||
state->got_code = true;
|
||||
}
|
||||
|
||||
static void group_message_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, TOX_MESSAGE_TYPE type,
|
||||
const uint8_t *message, size_t length, uint32_t message_id, void *user_data)
|
||||
static void group_message_handler(const Tox_Event_Group_Message *event, void *user_data)
|
||||
{
|
||||
const uint8_t *message = tox_event_group_message_get_message(event);
|
||||
const size_t length = tox_event_group_message_get_message_length(event);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
@ -133,12 +146,12 @@ static void group_tcp_test(AutoTox *autotoxes)
|
||||
State *state1 = (State *)autotoxes[1].state;
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
tox_callback_group_peer_join(autotoxes[i].tox, group_peer_join_handler);
|
||||
tox_callback_group_private_message(autotoxes[i].tox, group_private_message_handler);
|
||||
tox_events_callback_group_peer_join(autotoxes[i].dispatch, group_peer_join_handler);
|
||||
tox_events_callback_group_private_message(autotoxes[i].dispatch, group_private_message_handler);
|
||||
}
|
||||
|
||||
tox_callback_group_message(autotoxes[1].tox, group_message_handler);
|
||||
tox_callback_group_invite(autotoxes[1].tox, group_invite_handler);
|
||||
tox_events_callback_group_message(autotoxes[1].dispatch, group_message_handler);
|
||||
tox_events_callback_group_invite(autotoxes[1].dispatch, group_invite_handler);
|
||||
|
||||
Tox_Err_Group_New new_err;
|
||||
uint32_t groupnumber = tox_group_new(autotoxes[0].tox, TOX_GROUP_PRIVACY_STATE_PUBLIC, (const uint8_t *)"test", 4,
|
||||
@ -147,11 +160,11 @@ static void group_tcp_test(AutoTox *autotoxes)
|
||||
|
||||
iterate_group(autotoxes, NUM_GROUP_TOXES, GROUP_ITERATION_INTERVAL);
|
||||
|
||||
Tox_Err_Group_State_Queries id_err;
|
||||
Tox_Err_Group_State_Query id_err;
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
|
||||
tox_group_get_chat_id(autotoxes[0].tox, groupnumber, chat_id, &id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "%d", id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "%d", id_err);
|
||||
|
||||
printf("Tox 0 created new group...\n");
|
||||
|
||||
@ -168,7 +181,6 @@ static void group_tcp_test(AutoTox *autotoxes)
|
||||
printf("%d peers successfully joined. Waiting for code...\n", NUM_GROUP_TOXES);
|
||||
printf("Tox 0 sending secret code to all peers\n");
|
||||
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES - 1; ++i) {
|
||||
|
||||
Tox_Err_Group_Send_Private_Message perr;
|
||||
|
@ -55,8 +55,11 @@ static bool all_group_peers_connected(const AutoTox *autotoxes, uint32_t tox_cou
|
||||
return true;
|
||||
}
|
||||
|
||||
static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, void *user_data)
|
||||
static void group_peer_join_handler(const Tox_Event_Group_Peer_Join *event, void *user_data)
|
||||
{
|
||||
//const uint32_t group_number = tox_event_group_peer_join_get_group_number(event);
|
||||
const uint32_t peer_id = tox_event_group_peer_join_get_peer_id(event);
|
||||
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
@ -65,28 +68,41 @@ static void group_peer_join_handler(Tox *tox, uint32_t groupnumber, uint32_t pee
|
||||
state->peer_id = peer_id;
|
||||
}
|
||||
|
||||
static void group_topic_handler(Tox *tox, uint32_t groupnumber, uint32_t peer_id, const uint8_t *topic,
|
||||
size_t length, void *user_data)
|
||||
static void group_topic_handler(const Tox_Event_Group_Topic *event, void *user_data)
|
||||
{
|
||||
ck_assert(length <= TOX_GROUP_MAX_TOPIC_LENGTH);
|
||||
AutoTox *autotox = (AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
Tox_Err_Group_State_Queries query_err;
|
||||
const uint32_t group_number = tox_event_group_topic_get_group_number(event);
|
||||
//const uint32_t peer_id = tox_event_group_topic_get_peer_id(event);
|
||||
const uint8_t *topic = tox_event_group_topic_get_topic(event);
|
||||
const uint32_t topic_length = tox_event_group_topic_get_topic_length(event);
|
||||
|
||||
ck_assert(topic_length <= TOX_GROUP_MAX_TOPIC_LENGTH);
|
||||
|
||||
Tox_Err_Group_State_Query query_err;
|
||||
uint8_t topic2[TOX_GROUP_MAX_TOPIC_LENGTH];
|
||||
tox_group_get_topic(tox, groupnumber, topic2, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
tox_group_get_topic(autotox->tox, group_number, topic2, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
size_t topic_length = tox_group_get_topic_size(tox, groupnumber, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert_msg(topic_length == length && memcmp(topic, topic2, length) == 0,
|
||||
size_t topic_length_getter = tox_group_get_topic_size(autotox->tox, group_number, &query_err);
|
||||
ck_assert(query_err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
ck_assert_msg(topic_length_getter == topic_length && memcmp(topic, topic2, topic_length) == 0,
|
||||
"topic differs in callback: %s, %s", topic, topic2);
|
||||
}
|
||||
|
||||
static void group_topic_lock_handler(Tox *tox, uint32_t groupnumber, Tox_Group_Topic_Lock topic_lock, void *user_data)
|
||||
static void group_topic_lock_handler(const Tox_Event_Group_Topic_Lock *event, void *user_data)
|
||||
{
|
||||
Tox_Err_Group_State_Queries err;
|
||||
Tox_Group_Topic_Lock current_lock = tox_group_get_topic_lock(tox, groupnumber, &err);
|
||||
const AutoTox *autotox = (const AutoTox *)user_data;
|
||||
ck_assert(autotox != nullptr);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
const uint32_t group_number = tox_event_group_topic_lock_get_group_number(event);
|
||||
const Tox_Group_Topic_Lock topic_lock = tox_event_group_topic_lock_get_topic_lock(event);
|
||||
|
||||
Tox_Err_Group_State_Query err;
|
||||
Tox_Group_Topic_Lock current_lock = tox_group_get_topic_lock(autotox->tox, group_number, &err);
|
||||
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
ck_assert_msg(topic_lock == current_lock, "topic locks differ in callback");
|
||||
}
|
||||
|
||||
@ -107,10 +123,10 @@ static bool set_topic(Tox *tox, uint32_t groupnumber, const char *topic, size_t
|
||||
*/
|
||||
static int check_topic(const Tox *tox, uint32_t groupnumber, const char *expected_topic, size_t expected_length)
|
||||
{
|
||||
Tox_Err_Group_State_Queries query_err;
|
||||
Tox_Err_Group_State_Query query_err;
|
||||
size_t topic_length = tox_group_get_topic_size(tox, groupnumber, &query_err);
|
||||
|
||||
if (query_err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
|
||||
if (query_err != TOX_ERR_GROUP_STATE_QUERY_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -121,7 +137,7 @@ static int check_topic(const Tox *tox, uint32_t groupnumber, const char *expecte
|
||||
uint8_t topic[TOX_GROUP_MAX_TOPIC_LENGTH];
|
||||
tox_group_get_topic(tox, groupnumber, topic, &query_err);
|
||||
|
||||
if (query_err != TOX_ERR_GROUP_STATE_QUERIES_OK) {
|
||||
if (query_err != TOX_ERR_GROUP_STATE_QUERY_OK) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
@ -140,9 +156,9 @@ static void wait_topic_lock(AutoTox *autotoxes, uint32_t groupnumber, Tox_Group_
|
||||
uint32_t count = 0;
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
Tox_Err_Group_State_Queries err;
|
||||
Tox_Err_Group_State_Query err;
|
||||
Tox_Group_Topic_Lock topic_lock = tox_group_get_topic_lock(autotoxes[i].tox, groupnumber, &err);
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERIES_OK);
|
||||
ck_assert(err == TOX_ERR_GROUP_STATE_QUERY_OK);
|
||||
|
||||
if (topic_lock == expected_lock) {
|
||||
++count;
|
||||
@ -205,17 +221,18 @@ static void group_topic_test(AutoTox *autotoxes)
|
||||
{
|
||||
ck_assert_msg(NUM_GROUP_TOXES >= 3, "NUM_GROUP_TOXES is too small: %d", NUM_GROUP_TOXES);
|
||||
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
Tox *tox0 = autotoxes[0].tox;
|
||||
Tox_Dispatch *dispatch0 = autotoxes[0].dispatch;
|
||||
const State *state0 = (const State *)autotoxes[0].state;
|
||||
|
||||
tox_callback_group_peer_join(tox0, group_peer_join_handler);
|
||||
tox_events_callback_group_peer_join(dispatch0, group_peer_join_handler);
|
||||
|
||||
for (size_t i = 0; i < NUM_GROUP_TOXES; ++i) {
|
||||
tox_callback_group_topic(autotoxes[i].tox, group_topic_handler);
|
||||
tox_callback_group_topic_lock(autotoxes[i].tox, group_topic_lock_handler);
|
||||
tox_events_callback_group_topic(autotoxes[i].dispatch, group_topic_handler);
|
||||
tox_events_callback_group_topic_lock(autotoxes[i].dispatch, group_topic_lock_handler);
|
||||
}
|
||||
|
||||
/* Tox1 creates a group and is the founder of a newly created group */
|
||||
@ -233,11 +250,11 @@ static void group_topic_test(AutoTox *autotoxes)
|
||||
ck_assert_msg(s_ret, "Founder failed to set topic");
|
||||
|
||||
/* Founder gets the Chat ID and implicitly shares it publicly */
|
||||
Tox_Err_Group_State_Queries id_err;
|
||||
Tox_Err_Group_State_Query id_err;
|
||||
uint8_t chat_id[TOX_GROUP_CHAT_ID_SIZE];
|
||||
tox_group_get_chat_id(tox0, groupnumber, chat_id, &id_err);
|
||||
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERIES_OK, "tox_group_get_chat_id failed %d", id_err);
|
||||
ck_assert_msg(id_err == TOX_ERR_GROUP_STATE_QUERY_OK, "tox_group_get_chat_id failed %d", id_err);
|
||||
|
||||
/* All other peers join the group using the Chat ID */
|
||||
for (size_t i = 1; i < NUM_GROUP_TOXES; ++i) {
|
||||
@ -257,9 +274,9 @@ static void group_topic_test(AutoTox *autotoxes)
|
||||
wait_state_topic(autotoxes, groupnumber, TOPIC, TOPIC_LEN);
|
||||
|
||||
/* Founder disables topic lock */
|
||||
Tox_Err_Group_Founder_Set_Topic_Lock lock_set_err;
|
||||
tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d",
|
||||
Tox_Err_Group_Set_Topic_Lock lock_set_err;
|
||||
tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_DISABLED, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to disable topic lock: %d",
|
||||
lock_set_err);
|
||||
|
||||
fprintf(stderr, "Topic lock disabled\n");
|
||||
@ -273,9 +290,9 @@ static void group_topic_test(AutoTox *autotoxes)
|
||||
ck_assert_msg(change_count == NUM_GROUP_TOXES, "%u peers changed the topic with topic lock disabled", change_count);
|
||||
|
||||
/* founder silences the last peer he saw join */
|
||||
Tox_Err_Group_Mod_Set_Role merr;
|
||||
tox_group_mod_set_role(tox0, groupnumber, state0->peer_id, TOX_GROUP_ROLE_OBSERVER, &merr);
|
||||
ck_assert_msg(merr == TOX_ERR_GROUP_MOD_SET_ROLE_OK, "Failed to set %u to observer role: %d", state0->peer_id, merr);
|
||||
Tox_Err_Group_Set_Role merr;
|
||||
tox_group_set_role(tox0, groupnumber, state0->peer_id, TOX_GROUP_ROLE_OBSERVER, &merr);
|
||||
ck_assert_msg(merr == TOX_ERR_GROUP_SET_ROLE_OK, "Failed to set %u to observer role: %d", state0->peer_id, merr);
|
||||
|
||||
fprintf(stderr, "Random peer is set to observer\n");
|
||||
|
||||
@ -287,8 +304,8 @@ static void group_topic_test(AutoTox *autotoxes)
|
||||
ck_assert_msg(change_count == NUM_GROUP_TOXES - 1, "%u peers changed the topic with a silenced peer", change_count);
|
||||
|
||||
/* Founder enables topic lock and sets topic back to original */
|
||||
tox_group_founder_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_FOUNDER_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d",
|
||||
tox_group_set_topic_lock(tox0, groupnumber, TOX_GROUP_TOPIC_LOCK_ENABLED, &lock_set_err);
|
||||
ck_assert_msg(lock_set_err == TOX_ERR_GROUP_SET_TOPIC_LOCK_OK, "failed to enable topic lock: %d",
|
||||
lock_set_err);
|
||||
|
||||
fprintf(stderr, "Topic lock enabled\n");
|
||||
|
@ -18,13 +18,17 @@ typedef struct State {
|
||||
|
||||
#define LOSSLESS_PACKET_FILLER 160
|
||||
|
||||
static void handle_lossless_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
|
||||
static void handle_lossless_packet(const Tox_Event_Friend_Lossless_Packet *event, void *user_data)
|
||||
{
|
||||
//const uint32_t friend_number = tox_event_friend_lossless_packet_get_friend_number(event);
|
||||
const uint8_t *data = tox_event_friend_lossless_packet_get_data(event);
|
||||
const uint32_t data_length = tox_event_friend_lossless_packet_get_data_length(event);
|
||||
|
||||
uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size());
|
||||
ck_assert(cmp_packet != nullptr);
|
||||
memset(cmp_packet, LOSSLESS_PACKET_FILLER, tox_max_custom_packet_size());
|
||||
|
||||
if (length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) {
|
||||
if (data_length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) {
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
state->custom_packet_received = true;
|
||||
@ -35,7 +39,7 @@ static void handle_lossless_packet(Tox *tox, uint32_t friend_number, const uint8
|
||||
|
||||
static void test_lossless_packet(AutoTox *autotoxes)
|
||||
{
|
||||
tox_callback_friend_lossless_packet(autotoxes[1].tox, &handle_lossless_packet);
|
||||
tox_events_callback_friend_lossless_packet(autotoxes[1].dispatch, &handle_lossless_packet);
|
||||
const size_t packet_size = tox_max_custom_packet_size() + 1;
|
||||
uint8_t *packet = (uint8_t *)malloc(packet_size);
|
||||
ck_assert(packet != nullptr);
|
||||
|
@ -18,13 +18,17 @@ typedef struct State {
|
||||
|
||||
#define LOSSY_PACKET_FILLER 200
|
||||
|
||||
static void handle_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t *data, size_t length, void *user_data)
|
||||
static void handle_lossy_packet(const Tox_Event_Friend_Lossy_Packet *event, void *user_data)
|
||||
{
|
||||
//const uint32_t friend_number = tox_event_friend_lossy_packet_get_friend_number(event);
|
||||
const uint8_t *data = tox_event_friend_lossy_packet_get_data(event);
|
||||
const uint32_t data_length = tox_event_friend_lossy_packet_get_data_length(event);
|
||||
|
||||
uint8_t *cmp_packet = (uint8_t *)malloc(tox_max_custom_packet_size());
|
||||
ck_assert(cmp_packet != nullptr);
|
||||
memset(cmp_packet, LOSSY_PACKET_FILLER, tox_max_custom_packet_size());
|
||||
|
||||
if (length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) {
|
||||
if (data_length == tox_max_custom_packet_size() && memcmp(data, cmp_packet, tox_max_custom_packet_size()) == 0) {
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
state->custom_packet_received = true;
|
||||
@ -35,7 +39,7 @@ static void handle_lossy_packet(Tox *tox, uint32_t friend_number, const uint8_t
|
||||
|
||||
static void test_lossy_packet(AutoTox *autotoxes)
|
||||
{
|
||||
tox_callback_friend_lossy_packet(autotoxes[1].tox, &handle_lossy_packet);
|
||||
tox_events_callback_friend_lossy_packet(autotoxes[1].dispatch, &handle_lossy_packet);
|
||||
const size_t packet_size = tox_max_custom_packet_size() + 1;
|
||||
uint8_t *packet = (uint8_t *)malloc(packet_size);
|
||||
ck_assert(packet != nullptr);
|
||||
|
@ -20,7 +20,7 @@ static void test_addr_resolv_localhost(void)
|
||||
errno = 0;
|
||||
#endif
|
||||
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
|
||||
const char localhost[] = "localhost";
|
||||
|
@ -37,7 +37,7 @@ static void do_onion(Mono_Time *mono_time, Onion *onion)
|
||||
static int handled_test_1;
|
||||
static int handle_test_1(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
|
||||
{
|
||||
Onion *onion = (Onion *)object;
|
||||
const Onion *onion = (const Onion *)object;
|
||||
|
||||
const char req_message[] = "Install Gentoo";
|
||||
uint8_t req_packet[1 + sizeof(req_message)];
|
||||
@ -99,7 +99,7 @@ static uint8_t test_3_pub_key[CRYPTO_PUBLIC_KEY_SIZE];
|
||||
static uint8_t test_3_ping_id[CRYPTO_SHA256_SIZE];
|
||||
static int handle_test_3(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
|
||||
{
|
||||
Onion *onion = (Onion *)object;
|
||||
const Onion *onion = (const Onion *)object;
|
||||
|
||||
if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
|
||||
return 1;
|
||||
@ -118,7 +118,6 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) {
|
||||
return 1;
|
||||
}
|
||||
@ -135,7 +134,7 @@ static int handle_test_3(void *object, const IP_Port *source, const uint8_t *pac
|
||||
static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length,
|
||||
void *userdata)
|
||||
{
|
||||
Onion *onion = (Onion *)object;
|
||||
const Onion *onion = (const Onion *)object;
|
||||
|
||||
if (length < ONION_ANNOUNCE_RESPONSE_MIN_SIZE || length > ONION_ANNOUNCE_RESPONSE_MAX_SIZE) {
|
||||
return 1;
|
||||
@ -154,7 +153,6 @@ static int handle_test_3_old(void *object, const IP_Port *source, const uint8_t
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (memcmp(packet + 1, sb_data, ONION_ANNOUNCE_SENDBACK_DATA_LENGTH) != 0) {
|
||||
return 1;
|
||||
}
|
||||
@ -171,7 +169,7 @@ static uint8_t nonce[CRYPTO_NONCE_SIZE];
|
||||
static int handled_test_4;
|
||||
static int handle_test_4(void *object, const IP_Port *source, const uint8_t *packet, uint16_t length, void *userdata)
|
||||
{
|
||||
Onion *onion = (Onion *)object;
|
||||
const Onion *onion = (const Onion *)object;
|
||||
|
||||
if (length != (1 + CRYPTO_NONCE_SIZE + CRYPTO_PUBLIC_KEY_SIZE + sizeof("Install gentoo") +
|
||||
CRYPTO_MAC_SIZE)) {
|
||||
@ -223,11 +221,11 @@ static Networking_Core *new_networking(const Logger *log, const Memory *mem, con
|
||||
static void test_basic(void)
|
||||
{
|
||||
uint32_t index[] = { 1, 2, 3 };
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
ck_assert(ns != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
|
||||
Logger *log1 = logger_new();
|
||||
@ -288,7 +286,7 @@ static void test_basic(void)
|
||||
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE, &handle_test_3, onion1);
|
||||
networking_registerhandler(onion1->net, NET_PACKET_ANNOUNCE_RESPONSE_OLD, &handle_test_3_old, onion1);
|
||||
ck_assert_msg((onion1_a != nullptr) && (onion2_a != nullptr), "Onion_Announce failed initializing.");
|
||||
uint8_t zeroes[64] = {0};
|
||||
const uint8_t zeroes[64] = {0};
|
||||
random_bytes(rng, sb_data, sizeof(sb_data));
|
||||
uint64_t s;
|
||||
memcpy(&s, sb_data, sizeof(uint64_t));
|
||||
@ -407,7 +405,7 @@ static Onions *new_onions(const Memory *mem, const Random *rng, uint16_t port, u
|
||||
{
|
||||
IP ip = get_loopback();
|
||||
ip.ip.v6.uint8[15] = 1;
|
||||
const Network *ns = system_network();
|
||||
const Network *ns = os_network();
|
||||
Onions *on = (Onions *)malloc(sizeof(Onions));
|
||||
|
||||
if (!on) {
|
||||
@ -576,9 +574,9 @@ static void test_announce(void)
|
||||
{
|
||||
uint32_t index[NUM_ONIONS];
|
||||
Onions *onions[NUM_ONIONS];
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const Memory *mem = system_memory();
|
||||
const Memory *mem = os_memory();
|
||||
ck_assert(mem != nullptr);
|
||||
|
||||
for (uint32_t i = 0; i < NUM_ONIONS; ++i) {
|
||||
|
@ -11,9 +11,13 @@ typedef struct State {
|
||||
|
||||
#define NUM_MSGS 40000
|
||||
|
||||
static void handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type,
|
||||
const uint8_t *message, size_t length, void *user_data)
|
||||
static void handle_friend_message(const Tox_Event_Friend_Message *event, void *user_data)
|
||||
{
|
||||
//const uint32_t friend_number = tox_event_friend_message_get_friend_number(event);
|
||||
//const Tox_Message_Type type = tox_event_friend_message_get_type(event);
|
||||
//const uint8_t *message = tox_event_friend_message_get_message(event);
|
||||
//const uint32_t message_length = tox_event_friend_message_get_message_length(event);
|
||||
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
state->recv_count++;
|
||||
@ -21,7 +25,7 @@ static void handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_
|
||||
|
||||
static void net_crypto_overflow_test(AutoTox *autotoxes)
|
||||
{
|
||||
tox_callback_friend_message(autotoxes[0].tox, handle_friend_message);
|
||||
tox_events_callback_friend_message(autotoxes[0].dispatch, handle_friend_message);
|
||||
|
||||
printf("sending many messages to tox0\n");
|
||||
|
||||
|
@ -24,10 +24,10 @@ static bool try_bootstrap(Tox *tox1, Tox *tox2, Tox *tox3, Tox *tox4)
|
||||
tox_self_get_connection_status(tox3) != TOX_CONNECTION_NONE &&
|
||||
tox_self_get_connection_status(tox4) != TOX_CONNECTION_NONE) {
|
||||
printf("%d %d %d %d\n",
|
||||
tox_self_get_connection_status(tox1),
|
||||
tox_self_get_connection_status(tox2),
|
||||
tox_self_get_connection_status(tox3),
|
||||
tox_self_get_connection_status(tox4));
|
||||
tox_self_get_connection_status(tox1),
|
||||
tox_self_get_connection_status(tox2),
|
||||
tox_self_get_connection_status(tox3),
|
||||
tox_self_get_connection_status(tox4));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -38,10 +38,10 @@ static bool try_bootstrap(Tox *tox1, Tox *tox2, Tox *tox3, Tox *tox4)
|
||||
|
||||
if (i % 10 == 0) {
|
||||
printf("%d %d %d %d\n",
|
||||
tox_self_get_connection_status(tox1),
|
||||
tox_self_get_connection_status(tox2),
|
||||
tox_self_get_connection_status(tox3),
|
||||
tox_self_get_connection_status(tox4));
|
||||
tox_self_get_connection_status(tox1),
|
||||
tox_self_get_connection_status(tox2),
|
||||
tox_self_get_connection_status(tox3),
|
||||
tox_self_get_connection_status(tox4));
|
||||
}
|
||||
|
||||
c_sleep(tox_iteration_interval(tox1));
|
||||
|
@ -51,7 +51,7 @@ static bool all_disconnected_from(uint32_t tox_count, AutoTox *autotoxes, uint32
|
||||
|
||||
static void test_reconnect(AutoTox *autotoxes)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
const time_t test_start_time = time(nullptr);
|
||||
|
||||
@ -67,7 +67,12 @@ static void test_reconnect(AutoTox *autotoxes)
|
||||
do {
|
||||
for (uint16_t i = 0; i < TOX_COUNT; ++i) {
|
||||
if (i != disconnect) {
|
||||
tox_iterate(autotoxes[i].tox, &autotoxes[i]);
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(autotoxes[i].tox, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(autotoxes[i].dispatch, events, &autotoxes[i]);
|
||||
tox_events_free(events);
|
||||
|
||||
autotoxes[i].clock += 1000;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOADED_SAVE_FILE "../auto_tests/data/save.tox"
|
||||
#define LOADED_SAVE_FILE_BIG "../auto_tests/data/save.tox.big"
|
||||
#define LOADED_SAVE_FILE_LITTLE "../auto_tests/data/save.tox.little"
|
||||
|
||||
// Information from the save file
|
||||
#define EXPECTED_NAME "name"
|
||||
@ -18,7 +19,7 @@
|
||||
#define EXPECTED_STATUS_MESSAGE_SIZE strlen(EXPECTED_STATUS_MESSAGE)
|
||||
#define EXPECTED_NUM_FRIENDS 1
|
||||
#define EXPECTED_NOSPAM "4C762C7D"
|
||||
#define EXPECTED_TOX_ID "B70E97D41F69B7F4C42A5BC7BD7A76B95B8030BE1B7C0E9E6FC19FC4ABEB195B4C762C7D800B"
|
||||
#define EXPECTED_TOX_ID "E776E9A993EE3CAE04F5946D9AC66FBBAA8C63A95A94B41942353C6DC1739B4B4C762C7DA7B9"
|
||||
|
||||
static size_t get_file_size(const char *save_path)
|
||||
{
|
||||
@ -135,6 +136,13 @@ static void test_save_compatibility(const char *save_path)
|
||||
tox_kill(tox);
|
||||
}
|
||||
|
||||
static bool is_little_endian(void)
|
||||
{
|
||||
uint16_t x = 1;
|
||||
return ((uint8_t *)&x)[0] == 1;
|
||||
}
|
||||
|
||||
// cppcheck-suppress constParameter
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char base_path[4096] = {0};
|
||||
@ -152,10 +160,15 @@ int main(int argc, char *argv[])
|
||||
base_path[strrchr(base_path, '/') - base_path] = '\0';
|
||||
}
|
||||
|
||||
char save_path[4096 + sizeof(LOADED_SAVE_FILE)];
|
||||
snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE);
|
||||
|
||||
test_save_compatibility(save_path);
|
||||
if (is_little_endian()) {
|
||||
char save_path[4096 + sizeof(LOADED_SAVE_FILE_LITTLE)];
|
||||
snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE_LITTLE);
|
||||
test_save_compatibility(save_path);
|
||||
} else {
|
||||
char save_path[4096 + sizeof(LOADED_SAVE_FILE_BIG)];
|
||||
snprintf(save_path, sizeof(save_path), "%s/%s", base_path, LOADED_SAVE_FILE_BIG);
|
||||
test_save_compatibility(save_path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,13 +22,12 @@ struct test_data {
|
||||
static void set_random(Tox *m, const Random *rng, bool (*setter)(Tox *, const uint8_t *, size_t, Tox_Err_Set_Info *), size_t length)
|
||||
{
|
||||
VLA(uint8_t, text, length);
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < length; ++i) {
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
text[i] = random_u08(rng);
|
||||
}
|
||||
|
||||
setter(m, text, SIZEOF_VLA(text), nullptr);
|
||||
setter(m, text, length, nullptr);
|
||||
}
|
||||
|
||||
static void alloc_string(uint8_t **to, size_t length)
|
||||
@ -44,18 +43,25 @@ static void set_string(uint8_t **to, const uint8_t *from, size_t length)
|
||||
memcpy(*to, from, length);
|
||||
}
|
||||
|
||||
static void namechange_callback(Tox *tox, uint32_t friend_number, const uint8_t *name, size_t length, void *user_data)
|
||||
static void namechange_callback(const Tox_Event_Friend_Name *event, void *user_data)
|
||||
{
|
||||
//const uint32_t friend_number = tox_event_friend_name_get_friend_number(event);
|
||||
const uint8_t *name = tox_event_friend_name_get_name(event);
|
||||
const uint32_t name_length = tox_event_friend_name_get_name_length(event);
|
||||
|
||||
struct test_data *to_compare = (struct test_data *)user_data;
|
||||
set_string(&to_compare->name, name, length);
|
||||
set_string(&to_compare->name, name, name_length);
|
||||
to_compare->received_name = true;
|
||||
}
|
||||
|
||||
static void statuschange_callback(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length,
|
||||
void *user_data)
|
||||
static void statuschange_callback(const Tox_Event_Friend_Status_Message *event, void *user_data)
|
||||
{
|
||||
//const uint32_t friend_number = tox_event_friend_status_message_get_friend_number(event);
|
||||
const uint8_t *message = tox_event_friend_status_message_get_message(event);
|
||||
const uint32_t message_length = tox_event_friend_status_message_get_message_length(event);
|
||||
|
||||
struct test_data *to_compare = (struct test_data *)user_data;
|
||||
set_string(&to_compare->status_message, message, length);
|
||||
set_string(&to_compare->status_message, message, message_length);
|
||||
to_compare->received_status_message = true;
|
||||
}
|
||||
|
||||
@ -65,6 +71,12 @@ int main(void)
|
||||
|
||||
Tox *const tox1 = tox_new_log(nullptr, nullptr, nullptr);
|
||||
Tox *const tox2 = tox_new_log(nullptr, nullptr, nullptr);
|
||||
ck_assert(tox1 != nullptr);
|
||||
ck_assert(tox2 != nullptr);
|
||||
|
||||
tox_events_init(tox1);
|
||||
Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch1 != nullptr);
|
||||
|
||||
printf("bootstrapping tox2 off tox1\n");
|
||||
uint8_t dht_key[TOX_PUBLIC_KEY_SIZE];
|
||||
@ -86,7 +98,7 @@ int main(void)
|
||||
ck_assert(reference_name != nullptr);
|
||||
ck_assert(reference_status != nullptr);
|
||||
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
set_random(tox1, rng, tox_self_set_name, tox_max_name_length());
|
||||
set_random(tox2, rng, tox_self_set_name, tox_max_name_length());
|
||||
@ -96,8 +108,8 @@ int main(void)
|
||||
tox_self_get_name(tox2, reference_name);
|
||||
tox_self_get_status_message(tox2, reference_status);
|
||||
|
||||
tox_callback_friend_name(tox1, namechange_callback);
|
||||
tox_callback_friend_status_message(tox1, statuschange_callback);
|
||||
tox_events_callback_friend_name(dispatch1, namechange_callback);
|
||||
tox_events_callback_friend_status_message(dispatch1, statuschange_callback);
|
||||
|
||||
while (true) {
|
||||
if (tox_self_get_connection_status(tox1) &&
|
||||
@ -107,7 +119,12 @@ int main(void)
|
||||
break;
|
||||
}
|
||||
|
||||
tox_iterate(tox1, &to_compare);
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox1, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch1, events, &to_compare);
|
||||
tox_events_free(events);
|
||||
|
||||
tox_iterate(tox2, nullptr);
|
||||
|
||||
c_sleep(tox_iteration_interval(tox1));
|
||||
@ -119,7 +136,12 @@ int main(void)
|
||||
break;
|
||||
}
|
||||
|
||||
tox_iterate(tox1, &to_compare);
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox1, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch1, events, &to_compare);
|
||||
tox_events_free(events);
|
||||
|
||||
tox_iterate(tox2, nullptr);
|
||||
|
||||
c_sleep(tox_iteration_interval(tox1));
|
||||
@ -146,6 +168,7 @@ int main(void)
|
||||
"incorrect status message: should be all zeroes");
|
||||
|
||||
tox_options_free(options);
|
||||
tox_dispatch_free(dispatch1);
|
||||
tox_kill(tox1);
|
||||
tox_kill(tox2);
|
||||
tox_kill(tox_to_compare);
|
||||
|
@ -32,16 +32,24 @@
|
||||
#endif
|
||||
#define TCP_RELAY_PORT 33431
|
||||
|
||||
static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
|
||||
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata)
|
||||
{
|
||||
if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
|
||||
tox_friend_add_norequest(m, public_key, nullptr);
|
||||
Tox *tox = (Tox *)userdata;
|
||||
|
||||
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
|
||||
const uint8_t *message = tox_event_friend_request_get_message(event);
|
||||
uint32_t message_length = tox_event_friend_request_get_message_length(event);
|
||||
|
||||
if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) {
|
||||
tox_friend_add_norequest(tox, public_key, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int connected_t1;
|
||||
static void tox_connection_status(Tox *tox, Tox_Connection connection_status, void *user_data)
|
||||
static void tox_connection_status(const Tox_Event_Self_Connection_Status *event, void *user_data)
|
||||
{
|
||||
const Tox_Connection connection_status = tox_event_self_connection_status_get_connection_status(event);
|
||||
|
||||
if (connected_t1 && !connection_status) {
|
||||
ck_abort_msg("Tox went offline");
|
||||
}
|
||||
@ -147,6 +155,9 @@ static void test_few_clients(void)
|
||||
Tox *tox1 = tox_new_log(opts1, &t_n_error, &index[0]);
|
||||
ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error);
|
||||
tox_options_free(opts1);
|
||||
tox_events_init(tox1);
|
||||
Tox_Dispatch *dispatch1 = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch1 != nullptr);
|
||||
|
||||
struct Tox_Options *opts2 = tox_options_new(nullptr);
|
||||
tox_options_set_ipv6_enabled(opts2, USE_IPV6);
|
||||
@ -154,6 +165,9 @@ static void test_few_clients(void)
|
||||
tox_options_set_local_discovery_enabled(opts2, false);
|
||||
Tox *tox2 = tox_new_log(opts2, &t_n_error, &index[1]);
|
||||
ck_assert_msg(t_n_error == TOX_ERR_NEW_OK, "Failed to create tox instance: %d", t_n_error);
|
||||
tox_events_init(tox2);
|
||||
Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch2 != nullptr);
|
||||
|
||||
struct Tox_Options *opts3 = tox_options_new(nullptr);
|
||||
tox_options_set_ipv6_enabled(opts3, USE_IPV6);
|
||||
@ -163,7 +177,6 @@ static void test_few_clients(void)
|
||||
|
||||
ck_assert_msg(tox1 && tox2 && tox3, "Failed to create 3 tox instances");
|
||||
|
||||
|
||||
Time_Data time_data;
|
||||
ck_assert_msg(pthread_mutex_init(&time_data.lock, nullptr) == 0, "Failed to init time_data mutex");
|
||||
time_data.clock = current_time_monotonic(tox1->mono_time);
|
||||
@ -183,8 +196,8 @@ static void test_few_clients(void)
|
||||
tox_bootstrap(tox3, "localhost", dht_port, dht_key, nullptr);
|
||||
|
||||
connected_t1 = 0;
|
||||
tox_callback_self_connection_status(tox1, tox_connection_status);
|
||||
tox_callback_friend_request(tox2, accept_friend_request);
|
||||
tox_events_callback_self_connection_status(dispatch1, tox_connection_status);
|
||||
tox_events_callback_friend_request(dispatch2, accept_friend_request);
|
||||
uint8_t address[TOX_ADDRESS_SIZE];
|
||||
tox_self_get_address(tox2, address);
|
||||
uint32_t test = tox_friend_add(tox3, address, (const uint8_t *)"Gentoo", 7, nullptr);
|
||||
@ -193,8 +206,20 @@ static void test_few_clients(void)
|
||||
uint8_t off = 1;
|
||||
|
||||
while (true) {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
{
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox1, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch1, events, tox1);
|
||||
tox_events_free(events);
|
||||
}
|
||||
{
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch2, events, tox2);
|
||||
tox_events_free(events);
|
||||
}
|
||||
tox_iterate(tox3, nullptr);
|
||||
|
||||
if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2)
|
||||
@ -220,9 +245,10 @@ static void test_few_clients(void)
|
||||
|
||||
// We're done with this callback, so unset it to ensure we don't fail the
|
||||
// test if tox1 goes offline while tox2 and 3 are reloaded.
|
||||
tox_callback_self_connection_status(tox1, nullptr);
|
||||
tox_events_callback_self_connection_status(dispatch1, nullptr);
|
||||
|
||||
reload_tox(&tox2, opts2, &index[1]);
|
||||
tox_events_init(tox2);
|
||||
|
||||
reload_tox(&tox3, opts3, &index[2]);
|
||||
|
||||
@ -231,8 +257,20 @@ static void test_few_clients(void)
|
||||
off = 1;
|
||||
|
||||
while (true) {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
{
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox1, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch1, events, tox1);
|
||||
tox_events_free(events);
|
||||
}
|
||||
{
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch2, events, tox2);
|
||||
tox_events_free(events);
|
||||
}
|
||||
tox_iterate(tox3, nullptr);
|
||||
|
||||
if (tox_self_get_connection_status(tox1) && tox_self_get_connection_status(tox2)
|
||||
@ -257,6 +295,9 @@ static void test_few_clients(void)
|
||||
|
||||
printf("test_few_clients succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time));
|
||||
|
||||
tox_dispatch_free(dispatch1);
|
||||
tox_dispatch_free(dispatch2);
|
||||
|
||||
tox_kill(tox1);
|
||||
tox_kill(tox2);
|
||||
tox_kill(tox3);
|
||||
|
@ -14,12 +14,15 @@ typedef struct State {
|
||||
#define MESSAGE_FILLER 'G'
|
||||
|
||||
static void message_callback(
|
||||
Tox *m, uint32_t friendnumber, Tox_Message_Type type,
|
||||
const uint8_t *string, size_t length, void *user_data)
|
||||
const Tox_Event_Friend_Message *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
const Tox_Message_Type type = tox_event_friend_message_get_type(event);
|
||||
const uint8_t *string = tox_event_friend_message_get_message(event);
|
||||
const uint32_t length = tox_event_friend_message_get_message_length(event);
|
||||
|
||||
if (type != TOX_MESSAGE_TYPE_NORMAL) {
|
||||
ck_abort_msg("Bad type");
|
||||
}
|
||||
@ -38,7 +41,7 @@ static void message_callback(
|
||||
|
||||
static void send_message_test(AutoTox *autotoxes)
|
||||
{
|
||||
tox_callback_friend_message(autotoxes[1].tox, &message_callback);
|
||||
tox_events_callback_friend_message(autotoxes[1].dispatch, &message_callback);
|
||||
|
||||
const size_t msgs_len = tox_max_message_length() + 1;
|
||||
uint8_t *msgs = (uint8_t *)malloc(msgs_len);
|
||||
|
@ -15,12 +15,16 @@
|
||||
|
||||
#define NICKNAME "Gentoo"
|
||||
|
||||
static void nickchange_callback(Tox *tox, uint32_t friendnumber, const uint8_t *string, size_t length, void *userdata)
|
||||
static void nickchange_callback(const Tox_Event_Friend_Name *event, void *user_data)
|
||||
{
|
||||
ck_assert_msg(length == sizeof(NICKNAME), "Name length not correct: %d != %d", (uint16_t)length,
|
||||
//const uint32_t friend_number = tox_event_friend_name_get_friend_number(event);
|
||||
const uint8_t *name = tox_event_friend_name_get_name(event);
|
||||
const uint32_t name_length = tox_event_friend_name_get_name_length(event);
|
||||
|
||||
ck_assert_msg(name_length == sizeof(NICKNAME), "Name length not correct: %d != %d", (uint16_t)name_length,
|
||||
(uint16_t)sizeof(NICKNAME));
|
||||
ck_assert_msg(memcmp(string, NICKNAME, sizeof(NICKNAME)) == 0, "Name not correct: %s", (const char *)string);
|
||||
bool *nickname_updated = (bool *)userdata;
|
||||
ck_assert_msg(memcmp(name, NICKNAME, sizeof(NICKNAME)) == 0, "Name not correct: %s", (const char *)name);
|
||||
bool *nickname_updated = (bool *)user_data;
|
||||
*nickname_updated = true;
|
||||
}
|
||||
|
||||
@ -34,6 +38,12 @@ static void test_set_name(void)
|
||||
|
||||
ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances");
|
||||
|
||||
// we only run events on tox2 in this test case
|
||||
tox_events_init(tox2);
|
||||
|
||||
Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch2 != nullptr);
|
||||
|
||||
printf("tox1 adds tox2 as friend, tox2 adds tox1\n");
|
||||
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_public_key(tox2, public_key);
|
||||
@ -50,7 +60,13 @@ static void test_set_name(void)
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
//tox_dispatch_invoke(dispatch2, events, nullptr);
|
||||
tox_events_free(events);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
} while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE ||
|
||||
tox_self_get_connection_status(tox2) == TOX_CONNECTION_NONE);
|
||||
@ -60,14 +76,20 @@ static void test_set_name(void)
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
//tox_dispatch_invoke(dispatch2, events, nullptr);
|
||||
tox_events_free(events);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
} while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP ||
|
||||
tox_friend_get_connection_status(tox2, 0, nullptr) != TOX_CONNECTION_UDP);
|
||||
|
||||
printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time));
|
||||
|
||||
tox_callback_friend_name(tox2, nickchange_callback);
|
||||
tox_events_callback_friend_name(dispatch2, nickchange_callback);
|
||||
Tox_Err_Set_Info err_n;
|
||||
bool ret = tox_self_set_name(tox1, (const uint8_t *)NICKNAME, sizeof(NICKNAME), &err_n);
|
||||
ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_name failed because %d\n", err_n);
|
||||
@ -76,7 +98,13 @@ static void test_set_name(void)
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, &nickname_updated);
|
||||
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch2, events, &nickname_updated);
|
||||
tox_events_free(events);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
} while (!nickname_updated);
|
||||
|
||||
@ -87,6 +115,8 @@ static void test_set_name(void)
|
||||
|
||||
printf("test_set_name succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time));
|
||||
|
||||
tox_dispatch_free(dispatch2);
|
||||
|
||||
tox_kill(tox1);
|
||||
tox_kill(tox2);
|
||||
}
|
||||
|
@ -15,9 +15,13 @@
|
||||
|
||||
#define STATUS_MESSAGE "Installing Gentoo"
|
||||
|
||||
static void status_callback(Tox *tox, uint32_t friend_number, const uint8_t *message, size_t length, void *user_data)
|
||||
static void status_callback(const Tox_Event_Friend_Status_Message *event, void *user_data)
|
||||
{
|
||||
ck_assert_msg(length == sizeof(STATUS_MESSAGE) &&
|
||||
//uint32_t friend_number = tox_event_friend_status_message_get_friend_number(event);
|
||||
const uint8_t *message = tox_event_friend_status_message_get_message(event);
|
||||
uint32_t message_length = tox_event_friend_status_message_get_message_length(event);
|
||||
|
||||
ck_assert_msg(message_length == sizeof(STATUS_MESSAGE) &&
|
||||
memcmp(message, STATUS_MESSAGE, sizeof(STATUS_MESSAGE)) == 0,
|
||||
"incorrect data in status callback");
|
||||
bool *status_updated = (bool *)user_data;
|
||||
@ -34,6 +38,12 @@ static void test_set_status_message(void)
|
||||
|
||||
ck_assert_msg(tox1 && tox2, "failed to create 2 tox instances");
|
||||
|
||||
// we only run events on tox2 in this test case
|
||||
tox_events_init(tox2);
|
||||
|
||||
Tox_Dispatch *dispatch2 = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch2 != nullptr);
|
||||
|
||||
printf("tox1 adds tox2 as friend, tox2 adds tox1\n");
|
||||
uint8_t public_key[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_public_key(tox2, public_key);
|
||||
@ -50,7 +60,12 @@ static void test_set_status_message(void)
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
//tox_dispatch_invoke(dispatch2, events, nullptr);
|
||||
tox_events_free(events);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
} while (tox_self_get_connection_status(tox1) == TOX_CONNECTION_NONE ||
|
||||
@ -61,7 +76,12 @@ static void test_set_status_message(void)
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, nullptr);
|
||||
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
//tox_dispatch_invoke(dispatch2, events, nullptr);
|
||||
tox_events_free(events);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
} while (tox_friend_get_connection_status(tox1, 0, nullptr) != TOX_CONNECTION_UDP ||
|
||||
@ -69,8 +89,8 @@ static void test_set_status_message(void)
|
||||
|
||||
printf("tox clients connected took %lu seconds\n", (unsigned long)(time(nullptr) - con_time));
|
||||
|
||||
tox_events_callback_friend_status_message(dispatch2, status_callback);
|
||||
Tox_Err_Set_Info err_n;
|
||||
tox_callback_friend_status_message(tox2, status_callback);
|
||||
bool ret = tox_self_set_status_message(tox1, (const uint8_t *)STATUS_MESSAGE, sizeof(STATUS_MESSAGE),
|
||||
&err_n);
|
||||
ck_assert_msg(ret && err_n == TOX_ERR_SET_INFO_OK, "tox_self_set_status_message failed because %d\n", err_n);
|
||||
@ -79,7 +99,13 @@ static void test_set_status_message(void)
|
||||
|
||||
do {
|
||||
tox_iterate(tox1, nullptr);
|
||||
tox_iterate(tox2, &status_updated);
|
||||
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(tox2, true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch2, events, &status_updated);
|
||||
tox_events_free(events);
|
||||
|
||||
c_sleep(ITERATION_INTERVAL);
|
||||
} while (!status_updated);
|
||||
|
||||
@ -92,6 +118,8 @@ static void test_set_status_message(void)
|
||||
|
||||
printf("test_set_status_message succeeded, took %lu seconds\n", (unsigned long)(time(nullptr) - cur_time));
|
||||
|
||||
tox_dispatch_free(dispatch2);
|
||||
|
||||
tox_kill(tox1);
|
||||
tox_kill(tox2);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
// Set to true to produce an msgpack file at /tmp/test.mp.
|
||||
static const bool want_dump_events = false;
|
||||
|
||||
static void handle_events_friend_message(Tox *tox, const Tox_Event_Friend_Message *event, void *user_data)
|
||||
static void handle_events_friend_message(const Tox_Event_Friend_Message *event, void *user_data)
|
||||
{
|
||||
bool *success = (bool *)user_data;
|
||||
|
||||
@ -84,7 +84,7 @@ static bool await_message(Tox **toxes, const Tox_Dispatch *dispatch)
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
tox_dispatch_invoke(dispatch, events, toxes[1], &success);
|
||||
tox_dispatch_invoke(dispatch, events, &success);
|
||||
print_events(sys, events);
|
||||
|
||||
if (success) {
|
||||
@ -169,22 +169,9 @@ static void test_tox_events(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void fake_test_unpack(void)
|
||||
{
|
||||
// TODO(Green-Sky): add proper unpack tests and/or implement ngc events
|
||||
(void)tox_group_privacy_state_unpack;
|
||||
(void)tox_group_privacy_state_unpack;
|
||||
(void)tox_group_voice_state_unpack;
|
||||
(void)tox_group_topic_lock_unpack;
|
||||
(void)tox_group_join_fail_unpack;
|
||||
(void)tox_group_mod_event_unpack;
|
||||
(void)tox_group_exit_type_unpack;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
setvbuf(stdout, nullptr, _IONBF, 0);
|
||||
test_tox_events();
|
||||
fake_test_unpack();
|
||||
return 0;
|
||||
}
|
||||
|
@ -26,16 +26,27 @@
|
||||
#define TOX_LOCALHOST "127.0.0.1"
|
||||
#endif
|
||||
|
||||
typedef struct State {
|
||||
uint32_t to_comp;
|
||||
Tox *tox;
|
||||
} State;
|
||||
|
||||
static bool enable_broken_tests = false;
|
||||
|
||||
static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
|
||||
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata)
|
||||
{
|
||||
if (*((uint32_t *)userdata) != 974536) {
|
||||
State *state = (State *)userdata;
|
||||
|
||||
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
|
||||
const uint8_t *message = tox_event_friend_request_get_message(event);
|
||||
const uint32_t message_length = tox_event_friend_request_get_message_length(event);
|
||||
|
||||
if (state->to_comp != 974536) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
|
||||
tox_friend_add_norequest(m, public_key, nullptr);
|
||||
if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) {
|
||||
tox_friend_add_norequest(state->tox, public_key, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +57,7 @@ static uint16_t tcp_relay_port = 33448;
|
||||
|
||||
static void test_many_clients_tcp(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
long long unsigned int cur_time = time(nullptr);
|
||||
Tox *toxes[NUM_TOXES_TCP];
|
||||
@ -73,7 +84,7 @@ static void test_many_clients_tcp(void)
|
||||
continue;
|
||||
}
|
||||
ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i);
|
||||
tox_callback_friend_request(toxes[i], accept_friend_request);
|
||||
tox_events_init(toxes[i]);
|
||||
uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_dht_id(toxes[0], dpk);
|
||||
Tox_Err_Bootstrap error;
|
||||
@ -85,6 +96,11 @@ static void test_many_clients_tcp(void)
|
||||
tox_options_free(opts);
|
||||
}
|
||||
|
||||
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch != nullptr);
|
||||
|
||||
tox_events_callback_friend_request(dispatch, accept_friend_request);
|
||||
|
||||
struct {
|
||||
uint16_t tox1;
|
||||
uint16_t tox2;
|
||||
@ -131,12 +147,18 @@ loop_top:
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
||||
tox_iterate(toxes[i], &to_comp);
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(toxes[i], true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
State state = {to_comp, toxes[i]};
|
||||
tox_dispatch_invoke(dispatch, events, &state);
|
||||
tox_events_free(events);
|
||||
}
|
||||
|
||||
c_sleep(50);
|
||||
}
|
||||
|
||||
tox_dispatch_free(dispatch);
|
||||
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
||||
tox_kill(toxes[i]);
|
||||
}
|
||||
@ -148,7 +170,7 @@ loop_top:
|
||||
|
||||
static void test_many_clients_tcp_b(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
long long unsigned int cur_time = time(nullptr);
|
||||
Tox *toxes[NUM_TOXES_TCP];
|
||||
@ -167,7 +189,7 @@ static void test_many_clients_tcp_b(void)
|
||||
index[i] = i + 1;
|
||||
toxes[i] = tox_new_log(opts, nullptr, &index[i]);
|
||||
ck_assert_msg(toxes[i] != nullptr, "Failed to create tox instances %u", i);
|
||||
tox_callback_friend_request(toxes[i], accept_friend_request);
|
||||
tox_events_init(toxes[i]);
|
||||
uint8_t dpk[TOX_PUBLIC_KEY_SIZE];
|
||||
tox_self_get_dht_id(toxes[(i % NUM_TCP_RELAYS)], dpk);
|
||||
ck_assert_msg(tox_add_tcp_relay(toxes[i], TOX_LOCALHOST, tcp_relay_port + (i % NUM_TCP_RELAYS), dpk, nullptr),
|
||||
@ -179,6 +201,11 @@ static void test_many_clients_tcp_b(void)
|
||||
tox_options_free(opts);
|
||||
}
|
||||
|
||||
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch != nullptr);
|
||||
|
||||
tox_events_callback_friend_request(dispatch, accept_friend_request);
|
||||
|
||||
struct {
|
||||
uint16_t tox1;
|
||||
uint16_t tox2;
|
||||
@ -232,12 +259,18 @@ loop_top:
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
||||
tox_iterate(toxes[i], &to_comp);
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(toxes[i], true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
State state = {to_comp, toxes[i]};
|
||||
tox_dispatch_invoke(dispatch, events, &state);
|
||||
tox_events_free(events);
|
||||
}
|
||||
|
||||
c_sleep(30);
|
||||
}
|
||||
|
||||
tox_dispatch_free(dispatch);
|
||||
for (uint32_t i = 0; i < NUM_TOXES_TCP; ++i) {
|
||||
tox_kill(toxes[i]);
|
||||
}
|
||||
@ -245,7 +278,6 @@ loop_top:
|
||||
printf("test_many_clients_tcp_b succeeded, took %llu seconds\n", time(nullptr) - cur_time);
|
||||
}
|
||||
|
||||
|
||||
static void tox_suite(void)
|
||||
{
|
||||
/* Each tox connects to a single tox TCP */
|
||||
|
@ -13,20 +13,25 @@
|
||||
#include "auto_test_support.h"
|
||||
#include "check_compat.h"
|
||||
|
||||
static void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
|
||||
static void accept_friend_request(const Tox_Event_Friend_Request *event, void *userdata)
|
||||
{
|
||||
if (length == 7 && memcmp("Gentoo", data, 7) == 0) {
|
||||
tox_friend_add_norequest(m, public_key, nullptr);
|
||||
Tox *tox = (Tox *)userdata;
|
||||
|
||||
const uint8_t *public_key = tox_event_friend_request_get_public_key(event);
|
||||
const uint8_t *message = tox_event_friend_request_get_message(event);
|
||||
const uint32_t message_length = tox_event_friend_request_get_message_length(event);
|
||||
|
||||
if (message_length == 7 && memcmp("Gentoo", message, 7) == 0) {
|
||||
tox_friend_add_norequest(tox, public_key, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define TCP_TEST_NUM_TOXES 90
|
||||
#define TCP_TEST_NUM_FRIENDS 50
|
||||
|
||||
static void test_many_clients(void)
|
||||
{
|
||||
const Random *rng = system_random();
|
||||
const Random *rng = os_random();
|
||||
ck_assert(rng != nullptr);
|
||||
time_t cur_time = time(nullptr);
|
||||
Tox *toxes[TCP_TEST_NUM_TOXES];
|
||||
@ -36,9 +41,14 @@ static void test_many_clients(void)
|
||||
index[i] = i + 1;
|
||||
toxes[i] = tox_new_log(nullptr, nullptr, &index[i]);
|
||||
ck_assert_msg(toxes[i] != nullptr, "failed to create tox instances %u", i);
|
||||
tox_callback_friend_request(toxes[i], accept_friend_request);
|
||||
tox_events_init(toxes[i]);
|
||||
}
|
||||
|
||||
Tox_Dispatch *dispatch = tox_dispatch_new(nullptr);
|
||||
ck_assert(dispatch != nullptr);
|
||||
|
||||
tox_events_callback_friend_request(dispatch, accept_friend_request);
|
||||
|
||||
struct {
|
||||
uint16_t tox1;
|
||||
uint16_t tox2;
|
||||
@ -112,12 +122,17 @@ loop_top:
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) {
|
||||
tox_iterate(toxes[i], nullptr);
|
||||
Tox_Err_Events_Iterate err = TOX_ERR_EVENTS_ITERATE_OK;
|
||||
Tox_Events *events = tox_events_iterate(toxes[i], true, &err);
|
||||
ck_assert(err == TOX_ERR_EVENTS_ITERATE_OK);
|
||||
tox_dispatch_invoke(dispatch, events, toxes[i]);
|
||||
tox_events_free(events);
|
||||
}
|
||||
|
||||
c_sleep(50);
|
||||
}
|
||||
|
||||
tox_dispatch_free(dispatch);
|
||||
for (uint32_t i = 0; i < TCP_TEST_NUM_TOXES; ++i) {
|
||||
tox_kill(toxes[i]);
|
||||
}
|
||||
|
9
auto_tests/tox_new_test.c
Normal file
9
auto_tests/tox_new_test.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include "../toxcore/tox.h"
|
||||
|
||||
#include "../toxcore/ccompat.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
tox_kill(tox_new(nullptr, nullptr));
|
||||
return 0;
|
||||
}
|
@ -23,7 +23,6 @@
|
||||
#define TEST_STOP_RESUME_PAYLOAD 1
|
||||
#define TEST_PAUSE_RESUME_SEND 1
|
||||
|
||||
|
||||
#define ck_assert_call_control(a, b, c) do { \
|
||||
Toxav_Err_Call_Control cc_err; \
|
||||
bool ok = toxav_call_control(a, b, c, &cc_err); \
|
||||
@ -34,7 +33,6 @@
|
||||
ck_assert(cc_err == TOXAV_ERR_CALL_CONTROL_OK); \
|
||||
} while (0)
|
||||
|
||||
|
||||
typedef struct {
|
||||
bool incoming;
|
||||
uint32_t state;
|
||||
@ -46,7 +44,6 @@ static void clear_call_control(CallControl *cc)
|
||||
*cc = empty;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callbacks
|
||||
*/
|
||||
@ -89,7 +86,6 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate helper
|
||||
*/
|
||||
@ -207,7 +203,6 @@ static void test_av_flows(void)
|
||||
c_sleep(20);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
Toxav_Err_New error;
|
||||
alice_av = toxav_new(alice, &error);
|
||||
|
@ -74,7 +74,6 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate helper
|
||||
*/
|
||||
@ -299,7 +298,6 @@ static void test_av_three_calls(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
tox_iterate(bootstrap, nullptr);
|
||||
tox_iterate(alice, nullptr);
|
||||
|
@ -17,10 +17,14 @@ typedef struct State {
|
||||
|
||||
#include "auto_test_support.h"
|
||||
|
||||
static void typing_callback(Tox *m, uint32_t friendnumber, bool typing, void *user_data)
|
||||
static void typing_callback(const Tox_Event_Friend_Typing *event, void *user_data)
|
||||
{
|
||||
const AutoTox *autotox = (AutoTox *)user_data;
|
||||
State *state = (State *)autotox->state;
|
||||
|
||||
//const uint32_t friend_number = tox_event_friend_typing_get_friend_number(event);
|
||||
const bool typing = tox_event_friend_typing_get_typing(event);
|
||||
|
||||
state->friend_is_typing = typing;
|
||||
}
|
||||
|
||||
@ -28,7 +32,7 @@ static void test_typing(AutoTox *autotoxes)
|
||||
{
|
||||
time_t cur_time = time(nullptr);
|
||||
|
||||
tox_callback_friend_typing(autotoxes[1].tox, &typing_callback);
|
||||
tox_events_callback_friend_typing(autotoxes[1].dispatch, &typing_callback);
|
||||
tox_self_set_typing(autotoxes[0].tox, 0, true, nullptr);
|
||||
|
||||
do {
|
||||
|
@ -48,8 +48,8 @@ function(_make_version_script target)
|
||||
endfunction()
|
||||
|
||||
option(STRICT_ABI "Enforce strict ABI export in dynamic libraries" OFF)
|
||||
if(WIN32 OR APPLE)
|
||||
# Windows and OSX don't have this linker functionality.
|
||||
if((WIN32 AND NOT MINGW) OR APPLE)
|
||||
# Windows and macOS don't have this linker functionality.
|
||||
set(STRICT_ABI OFF)
|
||||
endif()
|
||||
|
||||
|
@ -1295,15 +1295,6 @@ HTML_COLORSTYLE_SAT = 100
|
||||
|
||||
HTML_COLORSTYLE_GAMMA = 80
|
||||
|
||||
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
|
||||
# page will contain the date and time when the page was generated. Setting this
|
||||
# to YES can help to show when doxygen was last run and thus if the
|
||||
# documentation is up to date.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_TIMESTAMP = NO
|
||||
|
||||
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
||||
# documentation will contain a main index with vertical navigation menus that
|
||||
# are dynamically created via JavaScript. If disabled, the navigation index will
|
||||
@ -1950,14 +1941,6 @@ LATEX_HIDE_INDICES = NO
|
||||
|
||||
LATEX_BIB_STYLE = plain
|
||||
|
||||
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
|
||||
# page will contain the date and time when the page was generated. Setting this
|
||||
# to NO can help when comparing the output of multiple runs.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
LATEX_TIMESTAMP = NO
|
||||
|
||||
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# path from which the emoji images will be read. If a relative path is entered,
|
||||
# it will be relative to the LATEX_OUTPUT directory. If left blank the
|
||||
@ -2587,3 +2570,19 @@ GENERATE_LEGEND = YES
|
||||
# The default value is: YES.
|
||||
|
||||
DOT_CLEANUP = YES
|
||||
|
||||
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
|
||||
# clang parser for more accurate parsing at the cost of reduced performance.
|
||||
# This can be particularly helpful with template rich C++ code for which
|
||||
# doxygen's built-in parser lacks the necessary type information.
|
||||
|
||||
CLANG_ASSISTED_PARSING = NO
|
||||
|
||||
# If clang assisted parsing is enabled you can provide the clang parser with
|
||||
# the path to the directory containing a file called compile_commands.json.
|
||||
# This file is the compilation database containing the options used when the
|
||||
# source files were built. This is equivalent to specifying the -p option to a
|
||||
# clang tool, such as clang-check. These options will then be passed to the
|
||||
# parser. Any options specified with CLANG_OPTIONS will be added as well.
|
||||
|
||||
CLANG_DATABASE_PATH = _build
|
||||
|
@ -2,77 +2,122 @@ Group chats.
|
||||
|
||||
Note: we assume everyone in the chat trusts each other.
|
||||
|
||||
These group chats work by temporarily adding the 4 "closest" people defined by a distance function
|
||||
in group.c in order to form a circle of connected peers. These peers then relay messages to each other.
|
||||
|
||||
A friend invites another friend to a group chat by sending them an invite packet. The friend either ignores
|
||||
the invite or responds with a response packet if he wants to join the chat. The friend invite contains the type
|
||||
of groupchat (text only, A/V) the friend is being invited to.
|
||||
These group chats work by temporarily adding the 4 "closest" people defined by a
|
||||
distance function in group.c in order to form a circle of connected peers. These
|
||||
peers then relay messages to each other.
|
||||
|
||||
A friend invites another friend to a group chat by sending them an invite
|
||||
packet. The friend either ignores the invite or responds with a response packet
|
||||
if he wants to join the chat. The friend invite contains the type of groupchat
|
||||
(text only, A/V) the friend is being invited to.
|
||||
|
||||
TODO(irungentoo): write more of this.
|
||||
|
||||
## Protocol
|
||||
|
||||
Invite packets:
|
||||
Invite packet:
|
||||
|
||||
### Invite packet:
|
||||
|
||||
```
|
||||
[uint8_t id 96][uint8_t id 0][uint16_t group chat number][33 bytes group chat identifier[1 byte type][32 bytes id]]
|
||||
```
|
||||
|
||||
Response packet
|
||||
### Response packet
|
||||
|
||||
```
|
||||
[uint8_t id 96][uint8_t id 1][uint16_t group chat number(local)][uint16_t group chat number to join][33 bytes group chat identifier[1 byte type][32 bytes id]]
|
||||
```
|
||||
|
||||
### Peer online packet:
|
||||
|
||||
Peer online packet:
|
||||
```
|
||||
[uint8_t id 97][uint16_t group chat number (local)][33 bytes group chat identifier[1 byte type][32 bytes id]]
|
||||
```
|
||||
|
||||
Peer leave packet:
|
||||
### Peer leave packet:
|
||||
|
||||
```
|
||||
[uint8_t id 98][uint16_t group chat number][uint8_t id 1]
|
||||
```
|
||||
|
||||
Peer query packet:
|
||||
### Peer query packet:
|
||||
|
||||
```
|
||||
[uint8_t id 98][uint16_t group chat number][uint8_t id 8]
|
||||
```
|
||||
|
||||
Peer response packet:
|
||||
[uint8_t id 98][uint16_t group chat number][uint8_t id 9][Repeated times number of peers: [uint16_t peer num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key][uint8_t name length][name]]
|
||||
### Peer response packet:
|
||||
|
||||
Title response packet:
|
||||
```
|
||||
[uint8_t id 98][uint16_t group chat number][uint8_t id 9][Repeated times number of peers: [uint16_t peer num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key][uint8_t name length][name]]
|
||||
```
|
||||
|
||||
### Title response packet:
|
||||
|
||||
```
|
||||
[uint8_t id 98][uint16_t group chat number][uint8_t id 10][title]
|
||||
```
|
||||
|
||||
Message packets:
|
||||
### Message packets:
|
||||
|
||||
```
|
||||
[uint8_t id 99][uint16_t group chat number][uint16_t peer number][uint32_t message number][uint8_t with a value representing id of message][data]
|
||||
```
|
||||
|
||||
Lossy Message packets:
|
||||
### Lossy Message packets:
|
||||
|
||||
```
|
||||
[uint8_t id 199][uint16_t group chat number][uint16_t peer number][uint16_t message number][uint8_t with a value representing id of message][data]
|
||||
```
|
||||
|
||||
Group chat types:
|
||||
0: text
|
||||
1: AV
|
||||
## Group chat types:
|
||||
|
||||
- 0: text
|
||||
- 1: AV
|
||||
|
||||
Note: the message number is increased by 1 for each sent message.
|
||||
|
||||
message ids:
|
||||
0 - ping
|
||||
sent every ~60 seconds by every peer.
|
||||
No data.
|
||||
## message ids:
|
||||
|
||||
### 0 - ping
|
||||
|
||||
sent every ~60 seconds by every peer. No data.
|
||||
|
||||
### 16 - new_peer
|
||||
|
||||
16 - new_peer
|
||||
Tell everyone about a new peer in the chat.
|
||||
|
||||
```
|
||||
[uint16_t peer_num][uint8_t 32bytes real public key][uint8_t 32bytes temp DHT public key]
|
||||
```
|
||||
|
||||
17 - kill_peer
|
||||
### 17 - kill_peer
|
||||
|
||||
```
|
||||
[uint16_t peer_num]
|
||||
```
|
||||
|
||||
48 - name change
|
||||
### 48 - name change
|
||||
|
||||
```
|
||||
[uint8_t name[namelen]]
|
||||
```
|
||||
|
||||
49 - groupchat title change
|
||||
### 49 - groupchat title change
|
||||
|
||||
```
|
||||
[uint8_t title[titlelen]]
|
||||
```
|
||||
|
||||
64 - chat message
|
||||
### 64 - chat message
|
||||
|
||||
```
|
||||
[uint8_t message[messagelen]]
|
||||
```
|
||||
|
||||
65 - action (/me)
|
||||
### 65 - action (/me)
|
||||
|
||||
```
|
||||
[uint8_t message[messagelen]]
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
@ -1,51 +0,0 @@
|
||||
This folder contains the input file (``tox.in.h``) that has to be used to generate the ``tox.h`` api with: https://github.com/TokTok/apidsl
|
||||
|
||||
# Minimal requirements
|
||||
|
||||
There are some minimal requirements to contribute to ``tox.h``:
|
||||
* unix environment
|
||||
* ``astyle`` ``>=2.03``
|
||||
* [``apidsl``](https://github.com/TokTok/apidsl) (you can use provided service with curl instead)
|
||||
|
||||
## Quick way
|
||||
|
||||
If you want to do it quickly and you don't have time for anything other than copypasting commands, you should have ``curl`` installed.
|
||||
|
||||
|
||||
1. Make sure that you have ``curl`` and ``>=astyle-2.03`` installed
|
||||
2. Modify [``tox.api.h``](/toxcore/tox.api.h)
|
||||
3. Run command below ↓
|
||||
|
||||
Command to run from ``toxcore`` directory (quick way, involves using curl):
|
||||
```bash
|
||||
# For tox.h:
|
||||
curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \
|
||||
< toxcore/tox.api.h \
|
||||
| astyle --options=other/astyle/astylerc \
|
||||
> toxcore/tox.h
|
||||
# For toxav.h:
|
||||
curl -X POST --data-binary @- https://apidsl.herokuapp.com/apidsl \
|
||||
< toxav/toxav.api.h \
|
||||
| astyle --options=other/astyle/astylerc \
|
||||
> toxav/toxav.h
|
||||
```
|
||||
|
||||
You may want to make sure with ``git diff`` that changes made in ``tox.h`` reflect changes in ``tox.in.h``.
|
||||
|
||||
And you're done.
|
||||
|
||||
|
||||
## Manually
|
||||
|
||||
If you prefer to have more control over what is happening, there are steps below:
|
||||
|
||||
1. Install [``apidsl``](https://github.com/TokTok/apidsl)
|
||||
2. Install ``astyle``, version 2.03 or later.
|
||||
3. Modify [``tox.api.h``](/toxcore/tox.api.h)
|
||||
4. Use ``apidsl`` ``??``
|
||||
5. Parse generated ``tox.h`` with astyle, minimal command for it would be:
|
||||
```bash
|
||||
astyle --options=other/astyle/astylerc toxcore/tox.h
|
||||
```
|
||||
|
||||
**Always pass output from ``apidsl`` through astyle.**
|
129
docs/av_api.md
129
docs/av_api.md
@ -8,38 +8,36 @@
|
||||
phone_t* initPhone(uint16_t _listen_port, uint16_t _send_port);
|
||||
```
|
||||
|
||||
function initializes sample phone. _listen_port and _send_port are variables only meant
|
||||
for local testing. You will not have to do anything regarding to that since
|
||||
everything will be started within a messenger.
|
||||
function initializes sample phone. `_listen_port` and `_send_port` are variables
|
||||
only meant for local testing. You will not have to do anything regarding to that
|
||||
since everything will be started within a messenger.
|
||||
|
||||
|
||||
Phone requires one msi session and two rtp sessions ( one for audio and one for
|
||||
video ).
|
||||
Phone requires one msi session and two rtp sessions (one for audio and one for
|
||||
video).
|
||||
|
||||
```
|
||||
msi_session_t* msi_init_session( void* _core_handler, const uint8_t* _user_agent );
|
||||
```
|
||||
|
||||
initializes msi session.
|
||||
Params:
|
||||
initializes msi session. Params:
|
||||
|
||||
```
|
||||
void* _core_handler - pointer to an object handling networking,
|
||||
const uint8_t* _user_agent - string describing phone client version.
|
||||
```
|
||||
|
||||
Return value:
|
||||
msi_session_t* - pointer to a newly created msi session handler.
|
||||
Return value: `msi_session_t*` - pointer to a newly created msi session handler.
|
||||
|
||||
### msi_session_t reference:
|
||||
### `msi_session_t` reference:
|
||||
|
||||
How to handle msi session:
|
||||
Controlling is done via callbacks and action handlers.
|
||||
First register callbacks for every state/action received and make sure
|
||||
NOT TO PLACE SOMETHING LIKE LOOPS THAT TAKES A LOT OF TIME TO EXECUTE; every callback is being called
|
||||
directly from event loop. You can find examples in phone.c.
|
||||
How to handle msi session: Controlling is done via callbacks and action
|
||||
handlers. First register callbacks for every state/action received and make sure
|
||||
NOT TO PLACE SOMETHING LIKE LOOPS THAT TAKES A LOT OF TIME TO EXECUTE; every
|
||||
callback is being called directly from event loop. You can find examples in
|
||||
phone.c.
|
||||
|
||||
Register callbacks:
|
||||
|
||||
Register callbacks:
|
||||
```
|
||||
void msi_register_callback_call_started ( MCALLBACK );
|
||||
void msi_register_callback_call_canceled ( MCALLBACK );
|
||||
@ -55,10 +53,9 @@ void msi_register_callback_recv_error ( MCALLBACK );
|
||||
void msi_register_callback_requ_timeout ( MCALLBACK );
|
||||
```
|
||||
|
||||
MCALLBACK is defined as: void (*callback) (void* _arg)
|
||||
msi_session_t* handler is being thrown as \_arg so you can use that and \_agent_handler to get to your own phone handler
|
||||
directly from callback.
|
||||
|
||||
MCALLBACK is defined as: `void (*callback) (void* _arg)` `msi_session_t*`
|
||||
handler is being thrown as `_arg` so you can use that and `_agent_handler` to
|
||||
get to your own phone handler directly from callback.
|
||||
|
||||
Actions:
|
||||
|
||||
@ -66,80 +63,93 @@ Actions:
|
||||
int msi_invite ( msi_session_t* _session, call_type _call_type, uint32_t _timeoutms );
|
||||
```
|
||||
|
||||
Sends call invite. Before calling/sending invite msi_session_t::_friend_id is needed to be set or else
|
||||
it will not work. _call_type is type of the call ( Audio/Video ) and _timeoutms is how long
|
||||
will poll wait until request is terminated.
|
||||
Sends call invite. Before calling/sending invite `msi_session_t::_friend_id` is
|
||||
needed to be set or else it will not work. `_call_type` is type of the call (
|
||||
Audio/Video ) and `_timeoutms` is how long will poll wait until request is
|
||||
terminated.
|
||||
|
||||
```
|
||||
int msi_hangup ( msi_session_t* _session );
|
||||
```
|
||||
|
||||
Hangs up active call
|
||||
|
||||
```
|
||||
int msi_answer ( msi_session_t* _session, call_type _call_type );
|
||||
```
|
||||
Answer incoming call. _call_type set's callee call type.
|
||||
|
||||
Answer incoming call. `_call_type` set's callee call type.
|
||||
|
||||
```
|
||||
int msi_cancel ( msi_session_t* _session );
|
||||
```
|
||||
|
||||
Cancel current request.
|
||||
|
||||
```
|
||||
int msi_reject ( msi_session_t* _session );
|
||||
```
|
||||
Reject incoming call.
|
||||
|
||||
Reject incoming call.
|
||||
|
||||
### Now for rtp:
|
||||
|
||||
You will need 2 sessions; one for audio one for video.
|
||||
You start them with:
|
||||
You will need 2 sessions; one for audio one for video. You start them with:
|
||||
|
||||
```
|
||||
rtp_session_t* rtp_init_session ( int _max_users, int _multi_session );
|
||||
```
|
||||
|
||||
Params:
|
||||
|
||||
```
|
||||
int _max_users - max users. -1 if undefined
|
||||
int _multi_session - any positive number means uses multi session; -1 if not.
|
||||
```
|
||||
|
||||
Return value:
|
||||
|
||||
```
|
||||
rtp_session_t* - pointer to a newly created rtp session handler.
|
||||
```
|
||||
|
||||
### How to handle rtp session:
|
||||
|
||||
Take a look at
|
||||
|
||||
```
|
||||
void* phone_handle_media_transport_poll ( void* _hmtc_args_p ) in phone.c
|
||||
```
|
||||
|
||||
on example. Basically what you do is just receive a message via:
|
||||
|
||||
```
|
||||
struct rtp_msg_s* rtp_recv_msg ( rtp_session_t* _session );
|
||||
```
|
||||
|
||||
and then you use payload within the rtp_msg_s struct. Don't forget to deallocate it with:
|
||||
void rtp_free_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg );
|
||||
and then you use payload within the `rtp_msg_s` struct. Don't forget to
|
||||
deallocate it with:
|
||||
`void rtp_free_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg );`
|
||||
Receiving should be thread safe so don't worry about that.
|
||||
|
||||
When you capture and encode a payload you want to send it ( obviously ).
|
||||
|
||||
first create a new message with:
|
||||
|
||||
```
|
||||
struct rtp_msg_s* rtp_msg_new ( rtp_session_t* _session, const uint8_t* _data, uint32_t _length );
|
||||
```
|
||||
|
||||
and then send it with:
|
||||
|
||||
```
|
||||
int rtp_send_msg ( rtp_session_t* _session, struct rtp_msg_s* _msg, void* _core_handler );
|
||||
```
|
||||
|
||||
_core_handler is the same network handler as in msi_session_s struct.
|
||||
|
||||
`_core_handler` is the same network handler as in `msi_session_s` struct.
|
||||
|
||||
## A/V initialization:
|
||||
|
||||
```
|
||||
int init_receive_audio(codec_state *cs);
|
||||
int init_receive_video(codec_state *cs);
|
||||
@ -156,39 +166,62 @@ In the future, VP8 should be used directly and ffmpeg should be dropped from the
|
||||
The variable bps is the required bitrate in bits per second.
|
||||
```
|
||||
|
||||
|
||||
### A/V encoding/decoding:
|
||||
|
||||
```
|
||||
void *encode_video_thread(void *arg);
|
||||
```
|
||||
Spawns the video encoding thread. The argument should hold a pointer to a codec_state.
|
||||
This function should only be called if video encoding is supported (when init_send_video returns 1).
|
||||
Each video frame gets encoded into a packet, which is sent via RTP. Every 60 frames a new bidirectional interframe is encoded.
|
||||
|
||||
Spawns the video encoding thread. The argument should hold a pointer to a
|
||||
`codec_state`. This function should only be called if video encoding is
|
||||
supported (when `init_send_video` returns 1). Each video frame gets encoded into
|
||||
a packet, which is sent via RTP. Every 60 frames a new bidirectional interframe
|
||||
is encoded.
|
||||
|
||||
```
|
||||
void *encode_audio_thread(void *arg);
|
||||
```
|
||||
Spawns the audio encoding thread. The argument should hold a pointer to a codec_state.
|
||||
This function should only be called if audio encoding is supported (when init_send_audio returns 1).
|
||||
Audio frames are read from the selected audio capture device during initialisation. This audio capturing can be rerouted to a different device on the fly.
|
||||
Each audio frame is encoded into a packet, and sent via RTP. All audio frames have the same amount of samples, which is defined in AV_codec.h.
|
||||
|
||||
Spawns the audio encoding thread. The argument should hold a pointer to a
|
||||
`codec_state`. This function should only be called if audio encoding is
|
||||
supported (when `init_send_audio` returns 1). Audio frames are read from the
|
||||
selected audio capture device during initialisation. This audio capturing can be
|
||||
rerouted to a different device on the fly. Each audio frame is encoded into a
|
||||
packet, and sent via RTP. All audio frames have the same amount of samples,
|
||||
which is defined in `AV_codec.h`.
|
||||
|
||||
```
|
||||
int video_decoder_refresh(codec_state *cs, int width, int height);
|
||||
```
|
||||
Sets the SDL window dimensions and creates a pixel buffer with the requested size. It also creates a scaling context, which will be used to convert the input image format to YUV420P.
|
||||
|
||||
Sets the SDL window dimensions and creates a pixel buffer with the requested
|
||||
size. It also creates a scaling context, which will be used to convert the input
|
||||
image format to YUV420P.
|
||||
|
||||
```
|
||||
void *decode_video_thread(void *arg);
|
||||
```
|
||||
Spawns a video decoding thread. The argument should hold a pointer to a codec_state. The codec_state is assumed to contain a successfully initialised video decoder.
|
||||
This function reads video packets and feeds them to the video decoder. If the video frame's resolution has changed, video_decoder_refresh() is called. Afterwards, the frame is displayed on the SDL window.
|
||||
|
||||
Spawns a video decoding thread. The argument should hold a pointer to a
|
||||
`codec_state`. The `codec_state` is assumed to contain a successfully
|
||||
initialised video decoder. This function reads video packets and feeds them to
|
||||
the video decoder. If the video frame's resolution has changed,
|
||||
`video_decoder_refresh()` is called. Afterwards, the frame is displayed on the
|
||||
SDL window.
|
||||
|
||||
```
|
||||
void *decode_audio_thread(void *arg);
|
||||
```
|
||||
Spawns an audio decoding thread. The argument should hold a pointer to a codec_state. The codec_state is assumed to contain a successfully initialised audio decoder.
|
||||
All received audio packets are pushed into a jitter buffer and are reordered. If there is a missing packet, or a packet has arrived too late, it is treated as a lost packet and the audio decoder is informed of the packet loss. The audio decoder will then try to reconstruct the lost packet, based on information from previous packets.
|
||||
Audio is played on the default OpenAL output device.
|
||||
|
||||
Spawns an audio decoding thread. The argument should hold a pointer to a
|
||||
`codec_state`. The `codec_state` is assumed to contain a successfully
|
||||
initialised audio decoder. All received audio packets are pushed into a jitter
|
||||
buffer and are reordered. If there is a missing packet, or a packet has arrived
|
||||
too late, it is treated as a lost packet and the audio decoder is informed of
|
||||
the packet loss. The audio decoder will then try to reconstruct the lost packet,
|
||||
based on information from previous packets. Audio is played on the default
|
||||
OpenAL output device.
|
||||
|
||||
If you have any more qustions/bug reports/feature request contact the following users on the irc channel #tox-dev on irc.freenode.net:
|
||||
For RTP and MSI: mannol
|
||||
If you have any more qustions/bug reports/feature request contact the following
|
||||
users on the irc channel #tox-dev on irc.freenode.net: For RTP and MSI: mannol
|
||||
For audio and video: Martijnvdc
|
||||
|
111
docs/minpgc.md
111
docs/minpgc.md
@ -3,29 +3,29 @@
|
||||
This document describes the "minpgc" simple persistent conferences
|
||||
implementation of PR #1069.
|
||||
|
||||
Many of the ideas derive from isotoxin's persistent conferences
|
||||
implementation, PR #826.
|
||||
Many of the ideas derive from isotoxin's persistent conferences implementation,
|
||||
PR #826.
|
||||
|
||||
## Specification of changes from pre-existing conference specification
|
||||
|
||||
We add one new packet type:
|
||||
|
||||
Rejoin Conference packet
|
||||
|
||||
| Length | Contents |
|
||||
|:-------|:--------------------------------|
|
||||
| `1` | `uint8_t` (0x64) |
|
||||
| `33` | Group chat identifier |
|
||||
| Length | Contents |
|
||||
| :----- | :-------------------- |
|
||||
| `1` | `uint8_t` (0x64) |
|
||||
| `33` | Group chat identifier |
|
||||
|
||||
A peer times out from a group if it has been inactive for 60s. When a peer times
|
||||
out, we flag it as _frozen_. Frozen peers are disregarded for all purposes
|
||||
except those discussed below - in particular no packets are sent to them except
|
||||
as described below, they are omitted from the peer lists sent to the client or
|
||||
in a Peer Response packet, and they are not considered when determining closest
|
||||
peers for establishing direct connections.
|
||||
|
||||
A peer times out from a group if it has been inactive for 60s. When a peer
|
||||
times out, we flag it as _frozen_. Frozen peers are disregarded for all
|
||||
purposes except those discussed below - in particular no packets are sent to
|
||||
them except as described below, they are omitted from the peer lists sent to
|
||||
the client or in a Peer Response packet, and they are not considered when
|
||||
determining closest peers for establishing direct connections.
|
||||
|
||||
A peer is considered to be active if we receive a group message or Rejoin
|
||||
packet from it, or a New Peer message for it.
|
||||
A peer is considered to be active if we receive a group message or Rejoin packet
|
||||
from it, or a New Peer message for it.
|
||||
|
||||
If a frozen peer is seen to be active, we remove its 'frozen' flag and send a
|
||||
Name group message. (We can hold off on sending this message until the next
|
||||
@ -40,77 +40,83 @@ message. (This is current behaviour; it's mentioned here because it's important
|
||||
and not currently mentioned in the spec.)
|
||||
|
||||
If we receive a Rejoin packet from a peer we update its DHT pubkey, add a
|
||||
temporary groupchat connection for the peer, and, once the connection is
|
||||
online, send out a New Peer message announcing the peer, and a Name message.
|
||||
temporary groupchat connection for the peer, and, once the connection is online,
|
||||
send out a New Peer message announcing the peer, and a Name message.
|
||||
|
||||
Whenever we make a new friend connection, we check if the public key is that
|
||||
of any frozen peer. If so, we send it a Rejoin packet, add a temporary
|
||||
groupchat connection for it, and, once the connection is online, send the
|
||||
peer a Peer Query packet.
|
||||
Whenever we make a new friend connection, we check if the public key is that of
|
||||
any frozen peer. If so, we send it a Rejoin packet, add a temporary groupchat
|
||||
connection for it, and, once the connection is online, send the peer a Peer
|
||||
Query packet.
|
||||
|
||||
We do the same with a peer when we are setting it as frozen if we have a
|
||||
friend connection to it.
|
||||
We do the same with a peer when we are setting it as frozen if we have a friend
|
||||
connection to it.
|
||||
|
||||
The temporary groupchat connections established in sending and handling Rejoin
|
||||
packets are not immediately operational (because group numbers are not known);
|
||||
rather, an Online packet is sent when we handle a Rejoin packet.
|
||||
|
||||
When a connection is set as online as a result of an Online packet, we ping
|
||||
the group.
|
||||
When a connection is set as online as a result of an Online packet, we ping the
|
||||
group.
|
||||
|
||||
When processing the reply to a Peer Query, we update the DHT pubkey of an
|
||||
existing peer if and only if it is frozen or has not had its DHT pubkey
|
||||
updated since it last stopped being frozen.
|
||||
existing peer if and only if it is frozen or has not had its DHT pubkey updated
|
||||
since it last stopped being frozen.
|
||||
|
||||
When we receive a Title Response packet, we set the title if it has never been
|
||||
set or if at some point since it was last set, there were no unfrozen peers
|
||||
(except us).
|
||||
|
||||
## Discussion
|
||||
### Overview
|
||||
The intention is to recover seamlessly from splits in the group, the most
|
||||
common form of which is a single peer temporarily losing all connectivity.
|
||||
|
||||
To see how this works, first note that groups (even before the changes
|
||||
discussed here) have the property that for a group to be connected in the
|
||||
sense that any peer will receive the messages of any other peer and have them
|
||||
in their peerlist, it is necessary and sufficient that there is a path of
|
||||
direct group connections between any two peers.
|
||||
### Overview
|
||||
|
||||
The intention is to recover seamlessly from splits in the group, the most common
|
||||
form of which is a single peer temporarily losing all connectivity.
|
||||
|
||||
To see how this works, first note that groups (even before the changes discussed
|
||||
here) have the property that for a group to be connected in the sense that any
|
||||
peer will receive the messages of any other peer and have them in their
|
||||
peerlist, it is necessary and sufficient that there is a path of direct group
|
||||
connections between any two peers.
|
||||
|
||||
Now suppose the group is split into two connected components, with each member
|
||||
of one component frozen according to the members of the other. Suppose there
|
||||
are two peers, one in each component, which are using the above protocol, and
|
||||
of one component frozen according to the members of the other. Suppose there are
|
||||
two peers, one in each component, which are using the above protocol, and
|
||||
suppose they establish a friend connection. Then each will rejoin the other,
|
||||
forming a direct group connection. Hence the whole group will become connected
|
||||
(even if all other peers are using the unmodified protocol).
|
||||
|
||||
The Peer Query packet sent on rejoining hastens this process.
|
||||
|
||||
Peers who leave the group during a split will not be deleted by all peers
|
||||
after the merge - but they will be set as frozen due to ping timeouts, which
|
||||
is sufficient.
|
||||
Peers who leave the group during a split will not be deleted by all peers after
|
||||
the merge - but they will be set as frozen due to ping timeouts, which is
|
||||
sufficient.
|
||||
|
||||
### Titles
|
||||
If we have a split into components each containing multiple peers, and the
|
||||
title is changed in one component, then peers will continue to disagree on the
|
||||
title after the split. Short of a complicated voting system, this seems the
|
||||
only reasonable behaviour.
|
||||
|
||||
If we have a split into components each containing multiple peers, and the title
|
||||
is changed in one component, then peers will continue to disagree on the title
|
||||
after the split. Short of a complicated voting system, this seems the only
|
||||
reasonable behaviour.
|
||||
|
||||
### Implementation notes
|
||||
Although I've described the logic in terms of an 'frozen' flag, it might
|
||||
actually make more sense in the implementation to have a separate list for
|
||||
|
||||
Although I've described the logic in terms of an 'frozen' flag, it might
|
||||
actually make more sense in the implementation to have a separate list for
|
||||
frozen peers.
|
||||
|
||||
## Saving
|
||||
|
||||
Saving is implemented by simply saving all live groups with their group numbers
|
||||
and full peer info for all peers. On reload, all peers are set as frozen.
|
||||
|
||||
Clients needs to support this by understanding that groups may exist on
|
||||
start-up. Clients should call `tox_conference_get_chatlist` to obtain them. A
|
||||
group which is deleted (with `tox_conference_delete`) is removed permanently
|
||||
and will not be saved.
|
||||
group which is deleted (with `tox_conference_delete`) is removed permanently and
|
||||
will not be saved.
|
||||
|
||||
## Limitations
|
||||
|
||||
If a peer disconnects from the group for a period short enough that group
|
||||
timeouts do not occur, and a name change occurs during this period, then the
|
||||
name change will never be propagated.
|
||||
@ -120,9 +126,8 @@ requesting missed group messages. But this is considered out of scope of this
|
||||
PR.
|
||||
|
||||
If a peer changes its DHT pubkey, the change might not be properly propagated
|
||||
under various circumstances - in particular, if connections do not go down
|
||||
long enough for the peer to become frozen.
|
||||
under various circumstances - in particular, if connections do not go down long
|
||||
enough for the peer to become frozen.
|
||||
|
||||
One way to deal with this would be to add a group message announcing the
|
||||
sending peer's current DHT pubkey, and treat it analogously to the Name
|
||||
message.
|
||||
One way to deal with this would be to add a group message announcing the sending
|
||||
peer's current DHT pubkey, and treat it analogously to the Name message.
|
||||
|
@ -50,7 +50,6 @@ static const char *motd_str = ""; //Change this to anything within 256 bytes(but
|
||||
|
||||
#define PORT 33445
|
||||
|
||||
|
||||
static bool manage_keys(DHT *dht)
|
||||
{
|
||||
enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE };
|
||||
@ -61,7 +60,7 @@ static bool manage_keys(DHT *dht)
|
||||
if (keys_file != nullptr) {
|
||||
/* If file was opened successfully -- load keys,
|
||||
otherwise save new keys */
|
||||
size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
|
||||
const size_t read_size = fread(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
|
||||
|
||||
if (read_size != KEYS_SIZE) {
|
||||
printf("Error while reading the key file\nExiting.\n");
|
||||
@ -126,7 +125,7 @@ static void print_log(void *context, Logger_Level level, const char *file, int l
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc == 2 && !tox_strncasecmp(argv[1], "-h", 3)) {
|
||||
if (argc == 2 && tox_strncasecmp(argv[1], "-h", 3) == 0) {
|
||||
printf("Usage (connected) : %s [--ipv4|--ipv6] IP PORT KEY\n", argv[0]);
|
||||
printf("Usage (unconnected): %s [--ipv4|--ipv6]\n", argv[0]);
|
||||
return 0;
|
||||
@ -134,7 +133,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* let user override default by cmdline */
|
||||
bool ipv6enabled = TOX_ENABLE_IPV6_DEFAULT; /* x */
|
||||
int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
|
||||
const int argvoffset = cmdline_parsefor_ipv46(argc, argv, &ipv6enabled);
|
||||
|
||||
if (argvoffset < 0) {
|
||||
return 1;
|
||||
@ -151,9 +150,9 @@ int main(int argc, char *argv[])
|
||||
logger_callback_log(logger, print_log, nullptr, nullptr);
|
||||
}
|
||||
|
||||
const Random *rng = system_random();
|
||||
const Network *ns = system_network();
|
||||
const Memory *mem = system_memory();
|
||||
const Random *rng = os_random();
|
||||
const Network *ns = os_network();
|
||||
const Memory *mem = os_memory();
|
||||
|
||||
Mono_Time *mono_time = mono_time_new(mem, nullptr, nullptr);
|
||||
const uint16_t start_port = PORT;
|
||||
@ -165,11 +164,12 @@ int main(int argc, char *argv[])
|
||||
Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
|
||||
|
||||
#ifdef DHT_NODE_EXTRA_PACKETS
|
||||
bootstrap_set_callbacks(dht_get_net(dht), (uint32_t)DAEMON_VERSION_NUMBER, (const uint8_t *) motd_str, strlen(motd_str)+1);
|
||||
bootstrap_set_callbacks(dht_get_net(dht), (uint32_t)DAEMON_VERSION_NUMBER, (const uint8_t *) motd_str, strlen(motd_str) + 1);
|
||||
#endif
|
||||
|
||||
if (!(onion && forwarding && onion_a)) {
|
||||
if (onion == nullptr || forwarding == nullptr || onion_a == nullptr) {
|
||||
printf("Something failed to initialize.\n");
|
||||
// cppcheck-suppress resourceLeak
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -178,17 +178,19 @@ int main(int argc, char *argv[])
|
||||
perror("Initialization");
|
||||
|
||||
if (!manage_keys(dht)) {
|
||||
// cppcheck-suppress resourceLeak
|
||||
return 1;
|
||||
}
|
||||
printf("Public key: ");
|
||||
|
||||
#ifdef TCP_RELAY_ENABLED
|
||||
#define NUM_PORTS 3
|
||||
uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
|
||||
const uint16_t ports[NUM_PORTS] = {443, 3389, PORT};
|
||||
TCP_Server *tcp_s = new_tcp_server(logger, mem, rng, ns, ipv6enabled, NUM_PORTS, ports, dht_get_self_secret_key(dht), onion, forwarding);
|
||||
|
||||
if (tcp_s == nullptr) {
|
||||
printf("TCP server failed to initialize.\n");
|
||||
// cppcheck-suppress resourceLeak
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -199,6 +201,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (file == nullptr) {
|
||||
printf("Could not open file \"%s\" for writing. Exiting...\n", public_id_filename);
|
||||
// cppcheck-suppress resourceLeak
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -226,8 +229,8 @@ int main(int argc, char *argv[])
|
||||
const uint16_t port = net_htons((uint16_t)port_conv);
|
||||
|
||||
uint8_t *bootstrap_key = hex_string_to_bin(argv[argvoffset + 3]);
|
||||
int res = dht_bootstrap_from_address(dht, argv[argvoffset + 1],
|
||||
ipv6enabled, port, bootstrap_key);
|
||||
const bool res = dht_bootstrap_from_address(dht, argv[argvoffset + 1],
|
||||
ipv6enabled, port, bootstrap_key);
|
||||
free(bootstrap_key);
|
||||
|
||||
if (!res) {
|
||||
@ -236,17 +239,17 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
int is_waiting_for_dht_connection = 1;
|
||||
bool is_waiting_for_dht_connection = true;
|
||||
|
||||
uint64_t last_lan_discovery = 0;
|
||||
const Broadcast_Info *broadcast = lan_discovery_init(ns);
|
||||
|
||||
while (1) {
|
||||
while (true) {
|
||||
mono_time_update(mono_time);
|
||||
|
||||
if (is_waiting_for_dht_connection && dht_isconnected(dht)) {
|
||||
printf("Connected to other bootstrap node successfully.\n");
|
||||
is_waiting_for_dht_connection = 0;
|
||||
is_waiting_for_dht_connection = false;
|
||||
}
|
||||
|
||||
do_dht(dht);
|
||||
|
@ -3,17 +3,20 @@
|
||||
CHECKS="*"
|
||||
ERRORS="*"
|
||||
|
||||
# Can't fix this, because winsock has different HANDLE type than posix.
|
||||
# Still good to occasionally look at.
|
||||
ERRORS="$ERRORS,-google-readability-casting"
|
||||
|
||||
# Need to investigate or disable and document these.
|
||||
# =========================================================
|
||||
|
||||
# TODO(iphydf): Fix these.
|
||||
ERRORS="$ERRORS,-cert-err34-c"
|
||||
ERRORS="$ERRORS,-readability-suspicious-call-argument"
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-avoid-goto,-hicpp-avoid-goto"
|
||||
CHECKS="$CHECKS,-bugprone-incorrect-roundings"
|
||||
|
||||
# TODO(iphydf): Fix once cimple 0.0.19 is released.
|
||||
CHECKS="$CHECKS,-google-readability-casting"
|
||||
|
||||
# TODO(iphydf): Fix these.
|
||||
# TODO(iphydf): Fix this by making more functions set error code enums.
|
||||
CHECKS="$CHECKS,-bugprone-switch-missing-default-case"
|
||||
|
||||
# TODO(iphydf): We might want some of these. For the ones we don't want, add a
|
||||
@ -30,17 +33,22 @@ CHECKS="$CHECKS,-misc-no-recursion"
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-avoid-non-const-global-variables"
|
||||
|
||||
# TODO(iphydf): Probably fix these.
|
||||
CHECKS="$CHECKS,-cert-err33-c"
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-avoid-magic-numbers"
|
||||
CHECKS="$CHECKS,-readability-magic-numbers"
|
||||
|
||||
# TODO(iphydf): We're using a lot of macros for constants. Should we convert
|
||||
# all of them to enum?
|
||||
CHECKS="$CHECKS,-modernize-macro-to-enum"
|
||||
CHECKS="$CHECKS,-cert-err33-c,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers"
|
||||
|
||||
# Documented disabled checks. We don't want these for sure.
|
||||
# =========================================================
|
||||
|
||||
# We want to decay many arrays to pointers. In C, we do that all the time.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay"
|
||||
|
||||
# enum{} breaks comparisons and arithmetic in C++.
|
||||
CHECKS="$CHECKS,-modernize-macro-to-enum"
|
||||
|
||||
# For most things, we do want this, but for some we want to ensure (with msan)
|
||||
# that struct members are actually initialised with useful non-zero values.
|
||||
# Initialising them by default takes away that validation.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-pro-type-member-init,-hicpp-member-init"
|
||||
|
||||
# https://stackoverflow.com/questions/58672959/why-does-clang-tidy-say-vsnprintf-has-an-uninitialized-va-list-argument
|
||||
CHECKS="$CHECKS,-clang-analyzer-valist.Uninitialized"
|
||||
|
||||
@ -115,8 +123,7 @@ CHECKS="$CHECKS,-readability-redundant-control-flow"
|
||||
# ^
|
||||
# Trip the checker, which is true, because of integer promotion, but also not
|
||||
# very helpful as a diagnostic.
|
||||
CHECKS="$CHECKS,-bugprone-narrowing-conversions"
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-narrowing-conversions"
|
||||
CHECKS="$CHECKS,-bugprone-narrowing-conversions,-cppcoreguidelines-narrowing-conversions"
|
||||
|
||||
# Mistakenly thinks that
|
||||
# const int a = 0, b = 1;
|
||||
@ -135,9 +142,51 @@ CHECKS="$CHECKS,-cppcoreguidelines-narrowing-conversions"
|
||||
# - Turning 'a' and 'b' into pre-processor macros is the only option left, but
|
||||
# #defines and #undefs in the middle of a function hurt the readability and
|
||||
# are less idiomatic than simply using 'const int'.
|
||||
CHECKS="$CHECKS,-cert-dcl03-c"
|
||||
CHECKS="$CHECKS,-hicpp-static-assert"
|
||||
CHECKS="$CHECKS,-misc-static-assert"
|
||||
CHECKS="$CHECKS,-cert-dcl03-c,-hicpp-static-assert,-misc-static-assert"
|
||||
|
||||
# Doesn't consider use of preprocessor macros as needing a header, breaking
|
||||
# struct definitions that depend on size macros from e.g. crypto_core.h.
|
||||
CHECKS="$CHECKS,-misc-include-cleaner"
|
||||
|
||||
# A bunch of checks only valid for C++, we turn off for C.
|
||||
# =========================================================
|
||||
|
||||
# We don't use Google's int typedefs.
|
||||
CHECKS="$CHECKS,-google-runtime-int"
|
||||
# We write C code, so we use C arrays.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-avoid-c-arrays,-hicpp-avoid-c-arrays,-modernize-avoid-c-arrays"
|
||||
# C loops are ok. This one tells us to use range-for.
|
||||
CHECKS="$CHECKS,-modernize-loop-convert"
|
||||
# No auto in C.
|
||||
CHECKS="$CHECKS,-hicpp-use-auto,-modernize-use-auto"
|
||||
# Only C style casts in C.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-pro-type-cstyle-cast"
|
||||
# We use malloc (for now), and MISRA checks this too.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-no-malloc,-hicpp-no-malloc"
|
||||
# No owning_ptr<> in C.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-owning-memory"
|
||||
# void foo(void) is good in C.
|
||||
CHECKS="$CHECKS,-modernize-redundant-void-arg"
|
||||
# No using-typedefs in C.
|
||||
CHECKS="$CHECKS,-modernize-use-using"
|
||||
# No namespaces in C.
|
||||
CHECKS="$CHECKS,-misc-use-anonymous-namespace"
|
||||
# No trailing return type in C.
|
||||
CHECKS="$CHECKS,-modernize-use-trailing-return-type"
|
||||
# No <cstdint> and friends in C.
|
||||
CHECKS="$CHECKS,-hicpp-deprecated-headers,-modernize-deprecated-headers"
|
||||
# We use varargs for logging (we could reconsider, but right now we do).
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-cert-dcl50-cpp"
|
||||
# We do want to use the array index operator, even when the index is non-constant.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-constant-array-index"
|
||||
# We don't want to use pointer arithmetic, but this one includes array index
|
||||
# operators, which we do want to use.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-pro-bounds-pointer-arithmetic"
|
||||
# Can't use constexpr, yet. C will have it eventually, but it'll be years
|
||||
# until we can use it across all the compilers.
|
||||
CHECKS="$CHECKS,-cppcoreguidelines-macro-usage"
|
||||
# These are all very C++ and/or LLVM specific.
|
||||
CHECKS="$CHECKS,-llvmlibc-*"
|
||||
|
||||
set -eux
|
||||
|
||||
@ -154,7 +203,7 @@ copy_files() {
|
||||
find "${DIRS[@]}" \
|
||||
-maxdepth 1 -type d -exec mkdir -p "$1/{}" \;
|
||||
find "${DIRS[@]}" \
|
||||
-maxdepth 1 -name "*.c" -exec cp "{}" "$1/{}" \;
|
||||
-maxdepth 1 -name "*.[ch]" -exec cp "{}" "$1/{}" \;
|
||||
}
|
||||
|
||||
run() {
|
||||
@ -166,7 +215,7 @@ run() {
|
||||
ls .clang-tidy
|
||||
copy_files a
|
||||
if ! find "${DIRS[@]}" \
|
||||
-maxdepth 1 -name "*.c" -print0 \
|
||||
-maxdepth 1 -name "*.[ch]" -print0 \
|
||||
| xargs -0 -n15 -P"$(nproc)" clang-tidy \
|
||||
-p="$PWD/_build" \
|
||||
--extra-arg=-DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE \
|
||||
@ -184,5 +233,6 @@ run() {
|
||||
}
|
||||
|
||||
cmake . -B_build -GNinja -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
sed -i -e 's/-std=c11/-xc++/' _build/compile_commands.json
|
||||
|
||||
. other/analysis/variants.sh
|
||||
|
@ -1,5 +1,6 @@
|
||||
# Bracket Style Options
|
||||
--style=kr
|
||||
--attach-namespaces
|
||||
|
||||
# Tab Options
|
||||
--indent=spaces=4
|
||||
@ -9,15 +10,21 @@
|
||||
|
||||
# Padding Options
|
||||
--pad-header
|
||||
--break-blocks
|
||||
--pad-oper
|
||||
# Not supported in restyled's astyle.
|
||||
#--unpad-brackets
|
||||
--unpad-paren
|
||||
--align-pointer=name
|
||||
--align-reference=name
|
||||
# Disabled because it causes very large changes and it's unclear whether we
|
||||
# want all of those.
|
||||
#--squeeze-ws
|
||||
|
||||
# Formatting Options
|
||||
--add-braces
|
||||
--convert-tabs
|
||||
--max-code-length=120
|
||||
--max-code-length=200
|
||||
--attach-return-type
|
||||
|
||||
# Other Options
|
||||
--preserve-date
|
||||
|
@ -2,36 +2,6 @@
|
||||
|
||||
set -ex
|
||||
|
||||
SOURCE_DIR="$1"
|
||||
ASTYLE="$2"
|
||||
|
||||
# Go to the source root.
|
||||
if [ -z "$SOURCE_DIR" ]; then
|
||||
SOURCE_DIR=.
|
||||
fi
|
||||
cd "$SOURCE_DIR"
|
||||
|
||||
if [ -z "$ASTYLE" ] || ! which "$ASTYLE"; then
|
||||
ASTYLE=astyle
|
||||
fi
|
||||
|
||||
if ! which "$ASTYLE"; then
|
||||
# If we couldn't find or install an astyle binary, don't do anything.
|
||||
echo "Could not find an astyle binary; please install astyle."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
readarray -t CC_SOURCES <<<"$(find . '(' -name '*.cc' ')')"
|
||||
CC_SOURCES+=(toxcore/crypto_core.c)
|
||||
CC_SOURCES+=(toxcore/ping_array.c)
|
||||
|
||||
for bin in clang-format-11 clang-format-7 clang-format-6.0 clang-format-5.0 clang-format; do
|
||||
if which "$bin"; then
|
||||
"$bin" -i -style='{BasedOnStyle: Google, ColumnLimit: 100}' "${CC_SOURCES[@]}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
FIND="find ."
|
||||
FIND="$FIND '(' -name '*.[ch]' ')'"
|
||||
FIND="$FIND -and -not -name '*.api.h'"
|
||||
@ -40,7 +10,15 @@ FIND="$FIND -and -not -wholename './third_party/*'"
|
||||
FIND="$FIND -and -not -wholename './toxencryptsave/crypto_pwhash*'"
|
||||
|
||||
readarray -t C_SOURCES <<<"$(eval "$FIND")"
|
||||
readarray -t CC_SOURCES <<<"$(find . '(' -name '*.cc' -or -name '*.hh' ')')"
|
||||
#CC_SOURCES+=(toxcore/crypto_core.c)
|
||||
#CC_SOURCES+=(toxcore/ping_array.c)
|
||||
|
||||
"$ASTYLE" -n --options=other/astyle/astylerc "${C_SOURCES[@]}"
|
||||
# Format C++ sources with clang-format.
|
||||
clang-format -i "${CC_SOURCES[@]}"
|
||||
|
||||
# Format C sources with astyle. We can't use clang-format, because it strongly
|
||||
# messes up formatting of non_null annotations.
|
||||
astyle -n --options=other/astyle/astylerc "${C_SOURCES[@]}"
|
||||
|
||||
git diff --color=always --exit-code
|
||||
|
@ -48,8 +48,9 @@ RUN CC=clang cmake -B_build -H. \
|
||||
# Verify checksum from dev-built binary, so we can be sure Docker Hub doesn't
|
||||
# mess with your binaries.
|
||||
COPY other/bootstrap_daemon/docker/tox-bootstrapd.sha256 other/bootstrap_daemon/docker/
|
||||
RUN SHA256="$(sha256sum /usr/local/bin/tox-bootstrapd)" && \
|
||||
(sha256sum -c other/bootstrap_daemon/docker/tox-bootstrapd.sha256 || \
|
||||
ARG CHECK=sha256sum
|
||||
RUN SHA256="$("$CHECK" /usr/local/bin/tox-bootstrapd)" && \
|
||||
("$CHECK" -c other/bootstrap_daemon/docker/tox-bootstrapd.sha256 || \
|
||||
(echo "::error file=other/bootstrap_daemon/docker/tox-bootstrapd.sha256,line=1::$SHA256" && \
|
||||
false))
|
||||
|
||||
|
@ -1 +1 @@
|
||||
0b904988d79b9576bb88c6c7316d107b5a61bd6119a0992ebd7c1fa43db70abf /usr/local/bin/tox-bootstrapd
|
||||
af58a125e5c80d7a19bc7f32868c1edfdf80f366e3bf778728961a50ce63ee26 /usr/local/bin/tox-bootstrapd
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/**
|
||||
* Prints --help message
|
||||
*/
|
||||
@ -48,8 +47,8 @@ static void print_help(void)
|
||||
}
|
||||
|
||||
Cli_Status handle_command_line_arguments(
|
||||
int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend,
|
||||
bool *run_in_foreground)
|
||||
int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend,
|
||||
bool *run_in_foreground)
|
||||
{
|
||||
if (argc < 2) {
|
||||
log_write(LOG_LEVEL_ERROR, "Error: No arguments provided.\n\n");
|
||||
|
@ -32,7 +32,7 @@ typedef enum Cli_Status {
|
||||
* @param run_in_foreground Sets to the provided by the user foreground option.
|
||||
*/
|
||||
Cli_Status handle_command_line_arguments(
|
||||
int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend,
|
||||
bool *run_in_foreground);
|
||||
int argc, char *argv[], char **cfg_file_path, LOG_BACKEND *log_backend,
|
||||
bool *run_in_foreground);
|
||||
|
||||
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_COMMAND_LINE_ARGUMENTS_H
|
||||
|
@ -44,13 +44,13 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
|
||||
log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file.\n", NAME_TCP_RELAY_PORTS);
|
||||
log_write(LOG_LEVEL_WARNING, "Using default '%s':\n", NAME_TCP_RELAY_PORTS);
|
||||
|
||||
uint16_t default_ports[] = {DEFAULT_TCP_RELAY_PORTS};
|
||||
const uint16_t default_ports[] = {DEFAULT_TCP_RELAY_PORTS};
|
||||
|
||||
// Check to avoid calling malloc(0) later on
|
||||
// NOLINTNEXTLINE, clang-tidy: error: suspicious comparison of 'sizeof(expr)' to a constant [bugprone-sizeof-expression,-warnings-as-errors]
|
||||
static_assert(sizeof(default_ports) > 0, "At least one default TCP relay port should be provided");
|
||||
|
||||
const size_t default_ports_count = sizeof(default_ports)/sizeof(*default_ports);
|
||||
const size_t default_ports_count = sizeof(default_ports) / sizeof(*default_ports);
|
||||
|
||||
for (size_t i = 0; i < default_ports_count; ++i) {
|
||||
log_write(LOG_LEVEL_INFO, "Port #%zu: %u\n", i, default_ports[i]);
|
||||
@ -58,6 +58,10 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
|
||||
|
||||
// Similar procedure to the one of reading config file below
|
||||
*tcp_relay_ports = (uint16_t *)malloc(default_ports_count * sizeof(uint16_t));
|
||||
if (*tcp_relay_ports == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < default_ports_count; ++i) {
|
||||
|
||||
@ -73,10 +77,8 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
|
||||
++*tcp_relay_port_count;
|
||||
}
|
||||
|
||||
// The loop above skips invalid ports, so we adjust the allocated memory size
|
||||
if ((*tcp_relay_port_count) > 0) {
|
||||
*tcp_relay_ports = (uint16_t *)realloc(*tcp_relay_ports, (*tcp_relay_port_count) * sizeof(uint16_t));
|
||||
} else {
|
||||
// No ports, so we free the array.
|
||||
if (*tcp_relay_port_count == 0) {
|
||||
free(*tcp_relay_ports);
|
||||
*tcp_relay_ports = nullptr;
|
||||
}
|
||||
@ -90,7 +92,7 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
|
||||
return;
|
||||
}
|
||||
|
||||
int config_port_count = config_setting_length(ports_array);
|
||||
const int config_port_count = config_setting_length(ports_array);
|
||||
|
||||
if (config_port_count == 0) {
|
||||
log_write(LOG_LEVEL_ERROR, "'%s' is empty.\n", NAME_TCP_RELAY_PORTS);
|
||||
@ -98,6 +100,10 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
|
||||
}
|
||||
|
||||
*tcp_relay_ports = (uint16_t *)malloc(config_port_count * sizeof(uint16_t));
|
||||
if (*tcp_relay_ports == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < config_port_count; ++i) {
|
||||
config_setting_t *elem = config_setting_get_elem(ports_array, i);
|
||||
@ -125,18 +131,16 @@ static void parse_tcp_relay_ports_config(config_t *cfg, uint16_t **tcp_relay_por
|
||||
++*tcp_relay_port_count;
|
||||
}
|
||||
|
||||
// The loop above skips invalid ports, so we adjust the allocated memory size
|
||||
if ((*tcp_relay_port_count) > 0) {
|
||||
*tcp_relay_ports = (uint16_t *)realloc(*tcp_relay_ports, (*tcp_relay_port_count) * sizeof(uint16_t));
|
||||
} else {
|
||||
// No ports, so we free the array.
|
||||
if (*tcp_relay_port_count == 0) {
|
||||
free(*tcp_relay_ports);
|
||||
*tcp_relay_ports = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int 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 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)
|
||||
{
|
||||
config_t cfg;
|
||||
|
||||
@ -156,7 +160,7 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
|
||||
if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) {
|
||||
log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
|
||||
config_destroy(&cfg);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get port
|
||||
@ -177,6 +181,10 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
|
||||
|
||||
const size_t pid_file_path_len = strlen(tmp_pid_file) + 1;
|
||||
*pid_file_path = (char *)malloc(pid_file_path_len);
|
||||
if (*pid_file_path == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
|
||||
return false;
|
||||
}
|
||||
memcpy(*pid_file_path, tmp_pid_file, pid_file_path_len);
|
||||
|
||||
// Get keys file location
|
||||
@ -190,6 +198,10 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
|
||||
|
||||
const size_t keys_file_path_len = strlen(tmp_keys_file) + 1;
|
||||
*keys_file_path = (char *)malloc(keys_file_path_len);
|
||||
if (*keys_file_path == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
|
||||
return false;
|
||||
}
|
||||
memcpy(*keys_file_path, tmp_keys_file, keys_file_path_len);
|
||||
|
||||
// Get IPv6 option
|
||||
@ -223,7 +235,7 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
|
||||
*enable_tcp_relay = DEFAULT_ENABLE_TCP_RELAY;
|
||||
}
|
||||
|
||||
if (*enable_tcp_relay) {
|
||||
if (*enable_tcp_relay != 0) {
|
||||
parse_tcp_relay_ports_config(&cfg, tcp_relay_ports, tcp_relay_port_count);
|
||||
} else {
|
||||
*tcp_relay_port_count = 0;
|
||||
@ -237,7 +249,7 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
|
||||
*enable_motd = DEFAULT_ENABLE_MOTD;
|
||||
}
|
||||
|
||||
if (*enable_motd) {
|
||||
if (*enable_motd != 0) {
|
||||
// Get MOTD
|
||||
const char *tmp_motd;
|
||||
|
||||
@ -247,8 +259,8 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
|
||||
tmp_motd = DEFAULT_MOTD;
|
||||
}
|
||||
|
||||
size_t tmp_motd_length = strlen(tmp_motd) + 1;
|
||||
size_t motd_length = tmp_motd_length > MAX_MOTD_LENGTH ? MAX_MOTD_LENGTH : tmp_motd_length;
|
||||
const size_t tmp_motd_length = strlen(tmp_motd) + 1;
|
||||
const size_t motd_length = tmp_motd_length > MAX_MOTD_LENGTH ? MAX_MOTD_LENGTH : tmp_motd_length;
|
||||
*motd = (char *)malloc(motd_length);
|
||||
snprintf(*motd, motd_length, "%s", tmp_motd);
|
||||
}
|
||||
@ -259,14 +271,14 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
|
||||
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 ? "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_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_TCP_RELAY, *enable_tcp_relay ? "true" : "false");
|
||||
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_TCP_RELAY, *enable_tcp_relay != 0 ? "true" : "false");
|
||||
|
||||
// Show info about tcp ports only if tcp relay is enabled
|
||||
if (*enable_tcp_relay) {
|
||||
if (*enable_tcp_relay != 0) {
|
||||
if (*tcp_relay_port_count == 0) {
|
||||
log_write(LOG_LEVEL_ERROR, "No TCP ports could be read.\n");
|
||||
} else {
|
||||
@ -278,13 +290,13 @@ int get_general_config(const char *cfg_file_path, char **pid_file_path, char **k
|
||||
}
|
||||
}
|
||||
|
||||
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd ? "true" : "false");
|
||||
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_ENABLE_MOTD, *enable_motd != 0 ? "true" : "false");
|
||||
|
||||
if (*enable_motd) {
|
||||
if (*enable_motd != 0) {
|
||||
log_write(LOG_LEVEL_INFO, "'%s': %s\n", NAME_MOTD, *motd);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -302,8 +314,12 @@ static uint8_t *bootstrap_hex_string_to_bin(const char *hex_string)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t len = strlen(hex_string) / 2;
|
||||
const size_t len = strlen(hex_string) / 2;
|
||||
uint8_t *ret = (uint8_t *)malloc(len);
|
||||
if (ret == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Allocation failure.\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *pos = hex_string;
|
||||
|
||||
@ -316,7 +332,7 @@ static uint8_t *bootstrap_hex_string_to_bin(const char *hex_string)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6)
|
||||
bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6)
|
||||
{
|
||||
const char *const NAME_BOOTSTRAP_NODES = "bootstrap_nodes";
|
||||
|
||||
@ -331,7 +347,7 @@ int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6)
|
||||
if (config_read_file(&cfg, cfg_file_path) == CONFIG_FALSE) {
|
||||
log_write(LOG_LEVEL_ERROR, "%s:%d - %s\n", config_error_file(&cfg), config_error_line(&cfg), config_error_text(&cfg));
|
||||
config_destroy(&cfg);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
config_setting_t *node_list = config_lookup(&cfg, NAME_BOOTSTRAP_NODES);
|
||||
@ -340,13 +356,13 @@ int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6)
|
||||
log_write(LOG_LEVEL_WARNING, "No '%s' setting in the configuration file. Skipping bootstrapping.\n",
|
||||
NAME_BOOTSTRAP_NODES);
|
||||
config_destroy(&cfg);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (config_setting_length(node_list) == 0) {
|
||||
log_write(LOG_LEVEL_WARNING, "No bootstrap nodes found. Skipping bootstrapping.\n");
|
||||
config_destroy(&cfg);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int bs_port;
|
||||
@ -357,15 +373,15 @@ int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6)
|
||||
|
||||
int i = 0;
|
||||
|
||||
while (config_setting_length(node_list)) {
|
||||
int address_resolved;
|
||||
while (config_setting_length(node_list) != 0) {
|
||||
bool address_resolved;
|
||||
uint8_t *bs_public_key_bin;
|
||||
|
||||
node = config_setting_get_elem(node_list, 0);
|
||||
|
||||
if (node == nullptr) {
|
||||
config_destroy(&cfg);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that all settings are present
|
||||
@ -421,5 +437,5 @@ next:
|
||||
|
||||
config_destroy(&cfg);
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
@ -19,19 +19,19 @@
|
||||
* also, iff `tcp_relay_ports_count` > 0, then you are responsible for freeing `tcp_relay_ports`
|
||||
* and also `motd` iff `enable_motd` is set.
|
||||
*
|
||||
* @return 1 on success,
|
||||
* 0 on failure, doesn't modify any data pointed by arguments.
|
||||
* @return true on success,
|
||||
* false on failure, doesn't modify any data pointed by arguments.
|
||||
*/
|
||||
int 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 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);
|
||||
|
||||
/**
|
||||
* Bootstraps off nodes listed in the config file.
|
||||
*
|
||||
* @return 1 on success, some or no bootstrap nodes were added
|
||||
* 0 on failure, an error occurred while parsing the config file.
|
||||
* @return true on success, some or no bootstrap nodes were added
|
||||
* false on failure, an error occurred while parsing the config file.
|
||||
*/
|
||||
int bootstrap_from_config(const char *cfg_file_path, DHT *dht, int enable_ipv6);
|
||||
bool bootstrap_from_config(const char *cfg_file_path, DHT *dht, bool enable_ipv6);
|
||||
|
||||
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_CONFIG_H
|
||||
|
@ -58,7 +58,6 @@ bool log_close(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool log_write(LOG_LEVEL level, const char *format, ...)
|
||||
{
|
||||
if (current_backend == INVALID_BACKEND) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "../../../toxcore/ccompat.h"
|
||||
#include "../../../toxcore/attributes.h"
|
||||
|
||||
typedef enum LOG_BACKEND {
|
||||
LOG_BACKEND_STDOUT,
|
||||
@ -47,5 +47,4 @@ bool log_close(void);
|
||||
*/
|
||||
bool log_write(LOG_LEVEL level, const char *format, ...) GNU_PRINTF(2, 3);
|
||||
|
||||
|
||||
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_H
|
||||
|
@ -10,10 +10,11 @@
|
||||
#ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H
|
||||
#define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../../../toxcore/attributes.h"
|
||||
#include "log.h"
|
||||
|
||||
void log_backend_stdout_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0);
|
||||
|
||||
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H
|
||||
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_STDOUT_H
|
||||
|
@ -51,7 +51,7 @@ void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args)
|
||||
va_list args2;
|
||||
|
||||
va_copy(args2, args);
|
||||
int size = vsnprintf(nullptr, 0, format, args2);
|
||||
const int size = vsnprintf(nullptr, 0, format, args2);
|
||||
va_end(args2);
|
||||
|
||||
assert(size >= 0);
|
||||
@ -61,6 +61,9 @@ void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args)
|
||||
}
|
||||
|
||||
char *buf = (char *)malloc(size + 1);
|
||||
if (buf == nullptr) {
|
||||
return;
|
||||
}
|
||||
vsnprintf(buf, size + 1, format, args);
|
||||
|
||||
syslog(log_backend_syslog_level(level), "%s", buf);
|
||||
|
@ -10,12 +10,13 @@
|
||||
#ifndef C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H
|
||||
#define C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../../../toxcore/attributes.h"
|
||||
#include "log.h"
|
||||
|
||||
void log_backend_syslog_open(void);
|
||||
void log_backend_syslog_close(void);
|
||||
void log_backend_syslog_write(LOG_LEVEL level, const char *format, va_list args) GNU_PRINTF(2, 0);
|
||||
|
||||
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H
|
||||
#endif // C_TOXCORE_OTHER_BOOTSTRAP_DAEMON_SRC_LOG_BACKEND_SYSLOG_H
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include "global.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
static void sleep_milliseconds(uint32_t ms)
|
||||
{
|
||||
struct timespec req;
|
||||
@ -61,10 +60,10 @@ static void sleep_milliseconds(uint32_t ms)
|
||||
|
||||
// Uses the already existing key or creates one if it didn't exist
|
||||
//
|
||||
// returns 1 on success
|
||||
// 0 on failure - no keys were read or stored
|
||||
// returns true on success
|
||||
// false on failure - no keys were read or stored
|
||||
|
||||
static int manage_keys(DHT *dht, const char *keys_file_path)
|
||||
static bool manage_keys(DHT *dht, const char *keys_file_path)
|
||||
{
|
||||
enum { KEYS_SIZE = CRYPTO_PUBLIC_KEY_SIZE + CRYPTO_SECRET_KEY_SIZE };
|
||||
uint8_t keys[KEYS_SIZE];
|
||||
@ -77,7 +76,7 @@ static int manage_keys(DHT *dht, const char *keys_file_path)
|
||||
|
||||
if (read_size != KEYS_SIZE) {
|
||||
fclose(keys_file);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
dht_set_self_public_key(dht, keys);
|
||||
@ -89,21 +88,21 @@ static int manage_keys(DHT *dht, const char *keys_file_path)
|
||||
|
||||
keys_file = fopen(keys_file_path, "wb");
|
||||
|
||||
if (!keys_file) {
|
||||
return 0;
|
||||
if (keys_file == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t write_size = fwrite(keys, sizeof(uint8_t), KEYS_SIZE, keys_file);
|
||||
|
||||
if (write_size != KEYS_SIZE) {
|
||||
fclose(keys_file);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(keys_file);
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prints public key
|
||||
@ -164,7 +163,6 @@ static Cli_Status daemonize(LOG_BACKEND log_backend, char *pid_file_path)
|
||||
return CLI_STATUS_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// Change the current working directory
|
||||
if ((chdir("/")) < 0) {
|
||||
log_write(LOG_LEVEL_ERROR, "Couldn't change working directory to '/'. Exiting.\n");
|
||||
@ -222,7 +220,7 @@ int main(int argc, char *argv[])
|
||||
bool run_in_foreground = false;
|
||||
|
||||
// Choose backend for printing command line argument parsing output based on whether the daemon is being run from a terminal
|
||||
LOG_BACKEND log_backend = isatty(STDOUT_FILENO) ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG;
|
||||
LOG_BACKEND log_backend = isatty(STDOUT_FILENO) != 0 ? LOG_BACKEND_STDOUT : LOG_BACKEND_SYSLOG;
|
||||
|
||||
log_open(log_backend);
|
||||
switch (handle_command_line_arguments(argc, argv, &cfg_file_path, &log_backend, &run_in_foreground)) {
|
||||
@ -283,7 +281,7 @@ int main(int argc, char *argv[])
|
||||
free(pid_file_path);
|
||||
|
||||
IP ip;
|
||||
ip_init(&ip, enable_ipv6);
|
||||
ip_init(&ip, enable_ipv6 != 0);
|
||||
|
||||
Logger *logger = logger_new();
|
||||
|
||||
@ -292,16 +290,16 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
const uint16_t end_port = start_port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM);
|
||||
const Memory *mem = system_memory();
|
||||
const Random *rng = system_random();
|
||||
const Network *ns = system_network();
|
||||
const Memory *mem = os_memory();
|
||||
const Random *rng = os_random();
|
||||
const Network *ns = os_network();
|
||||
Networking_Core *net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
|
||||
|
||||
if (net == nullptr) {
|
||||
if (enable_ipv6 && enable_ipv4_fallback) {
|
||||
if (enable_ipv6 != 0 && enable_ipv4_fallback != 0) {
|
||||
log_write(LOG_LEVEL_WARNING, "Couldn't initialize IPv6 networking. Falling back to using IPv4.\n");
|
||||
enable_ipv6 = 0;
|
||||
ip_init(&ip, enable_ipv6);
|
||||
ip_init(&ip, enable_ipv6 != 0);
|
||||
net = new_networking_ex(logger, mem, ns, &ip, start_port, end_port, nullptr);
|
||||
|
||||
if (net == nullptr) {
|
||||
@ -336,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);
|
||||
DHT *const dht = new_dht(logger, mem, rng, ns, mono_time, net, true, enable_lan_discovery != 0);
|
||||
|
||||
if (dht == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox DHT instance. Exiting.\n");
|
||||
@ -396,7 +394,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
Onion *onion = new_onion(logger, mem, mono_time, rng, dht);
|
||||
|
||||
if (!onion) {
|
||||
if (onion == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion. Exiting.\n");
|
||||
kill_gca(group_announce);
|
||||
kill_announcements(announce);
|
||||
@ -413,7 +411,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
Onion_Announce *onion_a = new_onion_announce(logger, mem, rng, mono_time, dht);
|
||||
|
||||
if (!onion_a) {
|
||||
if (onion_a == nullptr) {
|
||||
log_write(LOG_LEVEL_ERROR, "Couldn't initialize Tox Onion Announce. Exiting.\n");
|
||||
kill_gca(group_announce);
|
||||
kill_onion(onion);
|
||||
@ -431,7 +429,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
gca_onion_init(group_announce, onion_a);
|
||||
|
||||
if (enable_motd) {
|
||||
if (enable_motd != 0) {
|
||||
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);
|
||||
@ -474,7 +472,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
TCP_Server *tcp_server = nullptr;
|
||||
|
||||
if (enable_tcp_relay) {
|
||||
if (enable_tcp_relay != 0) {
|
||||
if (tcp_relay_port_count == 0) {
|
||||
log_write(LOG_LEVEL_ERROR, "No TCP relay ports read. Exiting.\n");
|
||||
kill_onion_announce(onion_a);
|
||||
@ -490,7 +488,7 @@ int main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6,
|
||||
tcp_server = new_tcp_server(logger, mem, rng, ns, enable_ipv6 != 0,
|
||||
tcp_relay_port_count, tcp_relay_ports,
|
||||
dht_get_self_secret_key(dht), onion, forwarding);
|
||||
|
||||
@ -506,7 +504,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
assert(rlim_suggested >= rlim_min);
|
||||
|
||||
if (!getrlimit(RLIMIT_NOFILE, &limit)) {
|
||||
if (getrlimit(RLIMIT_NOFILE, &limit) == 0) {
|
||||
if (limit.rlim_cur < limit.rlim_max) {
|
||||
// Some systems have a hard limit of over 1000000 open file descriptors, so let's cap it at something reasonable
|
||||
// so that we don't set it to an unreasonably high number.
|
||||
@ -515,7 +513,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (!getrlimit(RLIMIT_NOFILE, &limit) && limit.rlim_cur < rlim_min) {
|
||||
if (getrlimit(RLIMIT_NOFILE, &limit) == 0 && limit.rlim_cur < rlim_min) {
|
||||
log_write(LOG_LEVEL_WARNING,
|
||||
"Current limit on the number of files this process can open (%ju) is rather low for the proper functioning of the TCP server. "
|
||||
"Consider raising the limit to at least %ju or the recommended %ju. "
|
||||
@ -537,7 +535,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6)) {
|
||||
if (bootstrap_from_config(cfg_file_path, dht, enable_ipv6 != 0)) {
|
||||
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);
|
||||
@ -559,11 +557,11 @@ int main(int argc, char *argv[])
|
||||
uint64_t last_lan_discovery = 0;
|
||||
const uint16_t net_htons_port = net_htons(start_port);
|
||||
|
||||
int waiting_for_dht_connection = 1;
|
||||
bool waiting_for_dht_connection = true;
|
||||
|
||||
Broadcast_Info *broadcast = nullptr;
|
||||
|
||||
if (enable_lan_discovery) {
|
||||
if (enable_lan_discovery != 0) {
|
||||
broadcast = lan_discovery_init(ns);
|
||||
log_write(LOG_LEVEL_INFO, "Initialized LAN discovery successfully.\n");
|
||||
}
|
||||
@ -578,25 +576,25 @@ int main(int argc, char *argv[])
|
||||
// Prevent the signal handler from being called again before it returns
|
||||
sigfillset(&sa.sa_mask);
|
||||
|
||||
if (sigaction(SIGINT, &sa, nullptr)) {
|
||||
if (sigaction(SIGINT, &sa, nullptr) != 0) {
|
||||
log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGINT. Continuing without the signal handler set.\n");
|
||||
}
|
||||
|
||||
if (sigaction(SIGTERM, &sa, nullptr)) {
|
||||
if (sigaction(SIGTERM, &sa, nullptr) != 0) {
|
||||
log_write(LOG_LEVEL_WARNING, "Couldn't set signal handler for SIGTERM. Continuing without the signal handler set.\n");
|
||||
}
|
||||
|
||||
while (!caught_signal) {
|
||||
while (caught_signal == 0) {
|
||||
mono_time_update(mono_time);
|
||||
|
||||
do_dht(dht);
|
||||
|
||||
if (enable_lan_discovery && mono_time_is_timeout(mono_time, last_lan_discovery, LAN_DISCOVERY_INTERVAL)) {
|
||||
if (enable_lan_discovery != 0 && 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) {
|
||||
if (enable_tcp_relay != 0) {
|
||||
do_tcp_server(tcp_server, mono_time);
|
||||
}
|
||||
|
||||
@ -604,7 +602,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
if (waiting_for_dht_connection && dht_isconnected(dht)) {
|
||||
log_write(LOG_LEVEL_INFO, "Connected to another bootstrap node successfully.\n");
|
||||
waiting_for_dht_connection = 0;
|
||||
waiting_for_dht_connection = false;
|
||||
}
|
||||
|
||||
sleep_milliseconds(30);
|
||||
|
@ -2,6 +2,6 @@ module github.com/TokTok/c-toxcore/other/bootstrap_daemon/websocket/websockify
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/gorilla/websocket master
|
||||
)
|
||||
require github.com/gorilla/websocket v1.5.1
|
||||
|
||||
require golang.org/x/net v0.17.0 // indirect
|
||||
|
42
other/bootstrap_daemon/websocket/websockify/go.sum
Normal file
42
other/bootstrap_daemon/websocket/websockify/go.sum
Normal file
@ -0,0 +1,42 @@
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
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/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=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
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/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=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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/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/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/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=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
@ -18,6 +18,7 @@ package main
|
||||
import (
|
||||
"encoding/hex"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -104,7 +105,10 @@ func main() {
|
||||
if r.Header.Get("Upgrade") == "websocket" {
|
||||
serveWs(w, r)
|
||||
} else {
|
||||
http.ServeFile(w, r, r.URL.Path[1:])
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
|
||||
fmt.Fprintf(w, "404 Not Found")
|
||||
}
|
||||
})
|
||||
log.Fatal(http.ListenAndServe(*sourceAddr, nil))
|
||||
|
@ -35,7 +35,7 @@ static int handle_info_request(void *object, const IP_Port *source, const uint8_
|
||||
uint8_t data[1 + sizeof(bootstrap_version) + MAX_MOTD_LENGTH];
|
||||
data[0] = BOOTSTRAP_INFO_PACKET_ID;
|
||||
memcpy(data + 1, &bootstrap_version, sizeof(bootstrap_version));
|
||||
uint16_t len = 1 + sizeof(bootstrap_version) + bootstrap_motd_length;
|
||||
const uint16_t len = 1 + sizeof(bootstrap_version) + bootstrap_motd_length;
|
||||
memcpy(data + 1 + sizeof(bootstrap_version), bootstrap_motd, bootstrap_motd_length);
|
||||
|
||||
if (sendpacket(nc, source, data, len) == len) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
################################################
|
||||
# autotools-linux
|
||||
FROM toxchat/c-toxcore:sources AS sources
|
||||
FROM ubuntu:22.04
|
||||
|
||||
RUN apt-get update && \
|
||||
@ -24,7 +25,12 @@ USER builder
|
||||
|
||||
WORKDIR /home/builder
|
||||
|
||||
# Copy the sources and run the build.
|
||||
# Copy autotools-specific build scripts not present in the sources image.
|
||||
# These change less frequently than the sources, thus are copied first.
|
||||
COPY --chown=builder:builder . /home/builder/c-toxcore/
|
||||
|
||||
# Copy the sources and run the build.
|
||||
COPY --chown=builder:builder --from=sources /src/ /home/builder/c-toxcore/
|
||||
|
||||
WORKDIR /home/builder/c-toxcore
|
||||
RUN CC=gcc .github/scripts/autotools-linux
|
12
other/docker/autotools/autotools.Dockerfile.dockerignore
Normal file
12
other/docker/autotools/autotools.Dockerfile.dockerignore
Normal file
@ -0,0 +1,12 @@
|
||||
**/*
|
||||
!.github/scripts/autotools-linux
|
||||
!m4/*
|
||||
!configure.ac
|
||||
!*.pc.in
|
||||
!*.spec.in
|
||||
!**/Makefile.am
|
||||
!**/Makefile.inc
|
||||
!docs/updates/*
|
||||
!other/DHTnodes
|
||||
!other/astyle/*
|
||||
!other/tox.png
|
@ -2,4 +2,5 @@
|
||||
|
||||
set -eux
|
||||
BUILD=autotools
|
||||
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" .
|
||||
other/docker/sources/build
|
||||
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .
|
||||
|
@ -1,3 +1,4 @@
|
||||
FROM toxchat/c-toxcore:sources AS sources
|
||||
FROM alpine:3.19.0
|
||||
|
||||
RUN ["apk", "add", "--no-cache", \
|
||||
@ -16,6 +17,8 @@ RUN ["apk", "add", "--no-cache", \
|
||||
|
||||
ENV CC=clang CXX=clang++
|
||||
|
||||
COPY . /c-toxcore/
|
||||
COPY --from=sources /src/ /c-toxcore/
|
||||
COPY other/analysis/run-clang-tidy other/analysis/variants.sh /c-toxcore/other/analysis/
|
||||
COPY .clang-tidy /c-toxcore/
|
||||
WORKDIR /c-toxcore
|
||||
RUN other/analysis/run-clang-tidy
|
@ -2,4 +2,5 @@
|
||||
|
||||
set -eux
|
||||
BUILD=clang-tidy
|
||||
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" .
|
||||
other/docker/sources/build
|
||||
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .
|
||||
|
1
other/docker/compcert/.gitignore
vendored
Normal file
1
other/docker/compcert/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
!/Makefile
|
@ -1,30 +0,0 @@
|
||||
FROM toxchat/compcert:latest
|
||||
|
||||
WORKDIR /work
|
||||
COPY auto_tests/ /work/auto_tests/
|
||||
COPY testing/ /work/testing/
|
||||
COPY toxav/ /work/toxav/
|
||||
COPY toxcore/ /work/toxcore/
|
||||
COPY toxencryptsave/ /work/toxencryptsave/
|
||||
COPY third_party/ /work/third_party/
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
RUN ccomp \
|
||||
-o send_message_test \
|
||||
-Wall -Werror \
|
||||
-Wno-c11-extensions \
|
||||
-Wno-unknown-pragmas \
|
||||
-Wno-unused-variable \
|
||||
-fstruct-passing -fno-unprototyped -g \
|
||||
auto_tests/auto_test_support.c \
|
||||
auto_tests/send_message_test.c \
|
||||
testing/misc_tools.c \
|
||||
toxav/*.c \
|
||||
toxcore/*.c \
|
||||
toxcore/*/*.c \
|
||||
toxencryptsave/*.c \
|
||||
third_party/cmp/*.c \
|
||||
-D__COMPCERT__ -DDISABLE_VLA -Dinline= \
|
||||
-lpthread $(pkg-config --cflags --libs libsodium opus vpx) \
|
||||
&& ./send_message_test | grep 'tox clients connected'
|
39
other/docker/compcert/Makefile
Normal file
39
other/docker/compcert/Makefile
Normal file
@ -0,0 +1,39 @@
|
||||
CC := ccomp
|
||||
CFLAGS := -Wall \
|
||||
-Wno-c11-extensions \
|
||||
-Wno-unknown-pragmas \
|
||||
-Wno-unused-variable \
|
||||
-fstruct-passing -fno-unprototyped -g \
|
||||
-Ilibsodium/src/libsodium/include \
|
||||
$(shell pkg-config --cflags opus vpx)
|
||||
LDFLAGS := -lpthread $(shell pkg-config --libs opus vpx)
|
||||
|
||||
libsodium_SOURCES := $(shell find libsodium/src/libsodium -name "*.c")
|
||||
libsodium_OBJECTS := $(libsodium_SOURCES:.c=.o)
|
||||
|
||||
$(libsodium_OBJECTS): CFLAGS += \
|
||||
-DDEV_MODE \
|
||||
-DCONFIGURED \
|
||||
-D_DEFAULT_SOURCE \
|
||||
-Ilibsodium/builds/msvc \
|
||||
-Ilibsodium/src/libsodium/include/sodium
|
||||
|
||||
toxcore_SOURCES := $(wildcard \
|
||||
auto_tests/auto_test_support.c \
|
||||
auto_tests/send_message_test.c \
|
||||
testing/misc_tools.c \
|
||||
toxav/*.c \
|
||||
toxcore/*.c \
|
||||
toxcore/*/*.c \
|
||||
toxencryptsave/*.c \
|
||||
third_party/cmp/*.c)
|
||||
toxcore_OBJECTS := $(toxcore_SOURCES:.c=.o)
|
||||
$(toxcore_OBJECTS): CFLAGS += \
|
||||
-Werror \
|
||||
-D__COMPCERT__ \
|
||||
-DDISABLE_VLA \
|
||||
-DMIN_LOGGER_LEVEL=LOGGER_LEVEL_TRACE \
|
||||
-Dinline= \
|
||||
|
||||
send_message_test: $(libsodium_OBJECTS) $(toxcore_OBJECTS)
|
||||
$(CC) -o $@ $+ $(LDFLAGS)
|
19
other/docker/compcert/compcert.Dockerfile
Normal file
19
other/docker/compcert/compcert.Dockerfile
Normal file
@ -0,0 +1,19 @@
|
||||
FROM toxchat/c-toxcore:sources AS sources
|
||||
FROM toxchat/compcert:latest
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \
|
||||
gdb \
|
||||
make \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /work
|
||||
COPY --from=sources /src/ /work/
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
RUN git clone --depth=1 https://github.com/jedisct1/libsodium /work/libsodium
|
||||
COPY other/docker/compcert/Makefile /work/
|
||||
RUN make "-j$(nproc)"
|
||||
RUN ./send_message_test | grep 'tox clients connected'
|
@ -2,4 +2,5 @@
|
||||
|
||||
set -eux
|
||||
BUILD=compcert
|
||||
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/Dockerfile" .
|
||||
other/docker/sources/build
|
||||
docker build -t "toxchat/c-toxcore:$BUILD" -f "other/docker/$BUILD/$BUILD.Dockerfile" .
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM toxchat/c-toxcore:sources AS src
|
||||
FROM toxchat/c-toxcore:sources AS sources
|
||||
FROM ubuntu:20.04 AS build
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
@ -41,7 +41,7 @@ ENV CC=clang-17 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PATH=$PATH:/usr/lib/go-1.18/bin
|
||||
|
||||
COPY --from=src /src/ /work/
|
||||
COPY --from=sources /src/ /work/
|
||||
|
||||
WORKDIR /work
|
||||
RUN git clone --depth=1 https://github.com/TokTok/toktok-fuzzer /work/testing/fuzzing/toktok-fuzzer
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user