From 0e6efa0ef1b20521d4789a806d19860ec9ed6ae3 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sat, 24 Sep 2022 22:13:58 +0200 Subject: [PATCH 01/74] First step towards building a jar with libringrtc --- Makefile | 11 +++- bin/build-java | 144 ++++++++++++++++++++++++++++++++++++++++++++ src/rust/Cargo.toml | 1 + 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100755 bin/build-java diff --git a/Makefile b/Makefile index 4f514df9..53955456 100644 --- a/Makefile +++ b/Makefile @@ -32,10 +32,11 @@ help: $(Q) echo " ios -- download WebRTC and build for the iOS platform" $(Q) echo " android -- download WebRTC and build for the Android platform" $(Q) echo " electron -- build an Electron library" + $(Q) echo " java -- build a Java library" $(Q) echo " cli -- build the test cli (1:1 calls)" $(Q) echo " gctc -- build the test cli (group calls)" $(Q) echo - $(Q) echo "For the electon/cli/gctc builds, you can specify an optional platform" + $(Q) echo "For the electron/java/cli/gctc builds, you can specify an optional platform" $(Q) echo "which will download WebRTC. For example:" $(Q) echo " $ make electron PLATFORM=unix" $(Q) echo @@ -86,6 +87,14 @@ electron: fi $(Q) (cd src/node && yarn install && yarn build) +java: + $(Q) if [ "$(PLATFORM)" != "" ] ; then \ + echo "java: Preparing workspace for $(PLATFORM)" ; \ + ./bin/prepare-workspace $(PLATFORM) ; \ + fi + echo "java: Release build" ; \ + ./bin/build-java -r + cli: $(Q) if [ "$(PLATFORM)" != "" ] ; then \ echo "cli: Preparing workspace for $(PLATFORM)" ; \ diff --git a/bin/build-java b/bin/build-java new file mode 100755 index 00000000..4c26e833 --- /dev/null +++ b/bin/build-java @@ -0,0 +1,144 @@ +#!/bin/sh + +# +# Copyright 2019-2021 Signal Messenger, LLC +# SPDX-License-Identifier: AGPL-3.0-only +# + +set -e + +# shellcheck source=bin/env.sh +. "$(dirname "$0")"/env.sh + +TARGET_ARCH=${TARGET_ARCH:-x64} + +usage() +{ + echo 'usage: build-java [-d|-r|-c] + where: + -r to create a release build + -d to create a debug build (which may fail to build!) + -c to clean the build artifacts' +} + +clean() +{ + # Remove all possible artifact directories. + rm -rf ./src/rust/target/debug + rm -rf ./src/rust/target/release + rm -rf ./src/webrtc/src/out/debug + rm -rf ./src/webrtc/src/out/release +} + +BUILD_TYPE=release + +while [ "$1" != "" ]; do + case $1 in + -d | --debug ) + BUILD_TYPE=debug + ;; + -r | --release ) + BUILD_TYPE=release + ;; + -c | --clean ) + clean + exit + ;; + -h | --help ) + usage + exit + ;; + * ) + usage + exit 1 + esac + shift +done + +case "$TARGET_ARCH" in + "x64") + GN_ARCH=x64 + CARGO_ARCH=x86_64 + ;; + "ia32") + GN_ARCH=x86 + CARGO_ARCH=i686 + ;; + "arm64") + GN_ARCH=arm64 + CARGO_ARCH=aarch64 + ;; + *) + echo "Unsupported architecture" + exit 1 + ;; +esac + +hash rustup 2>/dev/null || { echo >&2 "Make sure you have rustup installed and properly configured! Aborting."; exit 1; } + +RUSTFLAGS_WIN= + +case "$(rustup show active-toolchain)" in + *"x86_64-apple-darwin"* | *"aarch64-apple-darwin"* ) + DEFAULT_PLATFORM="darwin" + CARGO_TARGET="${CARGO_ARCH}-apple-darwin" + ;; + *"x86_64-pc-windows"* ) + DEFAULT_PLATFORM="win32" + CARGO_TARGET="${CARGO_ARCH}-pc-windows-msvc" + # Static linking to prevent build errors on Windows ia32 + RUSTFLAGS_WIN="-C target-feature=+crt-static" + ;; + *"x86_64-unknown-linux"* ) + DEFAULT_PLATFORM="linux" + CARGO_TARGET="${CARGO_ARCH}-unknown-linux-gnu" + ;; + * ) + printf "Unknown platform detected!\nPlease make sure you have installed a valid Rust toolchain via rustup! Aborting.\n" + exit 1 +esac + +echo "Building for platform ${DEFAULT_PLATFORM}, TARGET_ARCH=${TARGET_ARCH}, GN_ARCH=${GN_ARCH}, CARGO_TARGET=${CARGO_TARGET}" + +export MACOSX_DEPLOYMENT_TARGET="10.10" + +# Build WebRTC. +( + cd src/webrtc/src + WEBRTC_ARGS="target_cpu=\"${GN_ARCH}\" rtc_build_examples=false rtc_build_tools=false rtc_include_tests=false rtc_enable_protobuf=false rtc_use_x11=false rtc_enable_sctp=false rtc_libvpx_build_vp9=true rtc_include_ilbc=false" + + if [ "${BUILD_TYPE}" = "debug" ] + then + gn gen -C "${OUTPUT_DIR}"/debug "--args=${WEBRTC_ARGS}" + ninja -C "${OUTPUT_DIR}"/debug + else + gn gen -C "${OUTPUT_DIR}"/release "--args=${WEBRTC_ARGS} is_debug=false" + ninja -C "${OUTPUT_DIR}"/release + fi +) + +# Build and link the final RingRTC library. +( + cd src/rust + + if [ "${BUILD_TYPE}" = "debug" ] + then + RUSTFLAGS="${RUSTFLAGS_WIN}" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --features java + else + RUSTFLAGS="-C link-arg=-s ${RUSTFLAGS_WIN}" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --features java --release + fi + + if [ $DEFAULT_PLATFORM = "darwin" ] + then + mkdir -p ../java/build/darwin + cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/build/darwin/libringrtc-"${TARGET_ARCH}".java + elif [ $DEFAULT_PLATFORM = "win32" ] + then + mkdir -p ../java/build/win32 + cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/ringrtc.dll ../java/build/win32/libringrtc-"${TARGET_ARCH}".java + elif [ $DEFAULT_PLATFORM = "linux" ] + then + mkdir -p ../java/build/linux + cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/build/linux/libringrtc-"${TARGET_ARCH}".java + fi +) diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index a52b6137..765cf0a9 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -69,6 +69,7 @@ webpki = { version = "0.21", optional = true } default = [] sim = ["rand_chacha"] electron = ["neon", "native"] +java = ["native"] native = [] # We have this so we can more easily disable things only native clients need simnet = [] # We have this so we can more easily disable things only simulated native client need http = ["ureq", "rustls", "webpki"] From f6b62c0ffb233aa4d1f33905f4837c4669e7e5ef Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 25 Sep 2022 21:21:14 +0200 Subject: [PATCH 02/74] Add maven code to build a jar with native library. --- bin/build-java | 8 ++- src/java/tring/pom.xml | 47 ++++++++++++ .../tring/NativeLibLoader.java | 17 +++++ src/rust/Cargo.lock | 71 +++++++++++++++++++ src/rust/Cargo.toml | 2 + src/rust/build.rs | 9 +++ src/rust/src/lib.rs | 7 ++ 7 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/java/tring/pom.xml create mode 100644 src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java diff --git a/bin/build-java b/bin/build-java index 4c26e833..9e6f2088 100755 --- a/bin/build-java +++ b/bin/build-java @@ -10,6 +10,8 @@ set -e # shellcheck source=bin/env.sh . "$(dirname "$0")"/env.sh +JEXTRACT=/opt/jextract-19 +JDK=/opt/jdk-19 TARGET_ARCH=${TARGET_ARCH:-x64} usage() @@ -125,7 +127,7 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" then RUSTFLAGS="${RUSTFLAGS_WIN}" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --features java else - RUSTFLAGS="-C link-arg=-s ${RUSTFLAGS_WIN}" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --features java --release + OUTPUT_DIR="${OUTPUT_DIR}" cargo build --lib --features java --release fi if [ $DEFAULT_PLATFORM = "darwin" ] @@ -139,6 +141,10 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" elif [ $DEFAULT_PLATFORM = "linux" ] then mkdir -p ../java/build/linux + cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/tring/src/main/resources/libringrtc.so cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/build/linux/libringrtc-"${TARGET_ARCH}".java fi + ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring -l ringrtc tringlib.h + cd ../java/tring + mvn clean install ) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml new file mode 100644 index 00000000..d99e8fb5 --- /dev/null +++ b/src/java/tring/pom.xml @@ -0,0 +1,47 @@ + + + 4.0.0 + io.privacyresearch + tring + 0.0.1-SNAPSHOT + jar + + UTF-8 + 19 + 19 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + --enable-preview + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + false + + + + + + + gluon-nexus + https://nexus.gluonhq.com/nexus/content/repositories/releases + + + gluon-nexus + https://nexus.gluonhq.com/nexus/content/repositories/public-snapshots + + + + diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java new file mode 100644 index 00000000..4a58cdd0 --- /dev/null +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java @@ -0,0 +1,17 @@ +package io.privacyresearch.tring; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + +public class NativeLibLoader { + + public static void loadLibrary() throws IOException { + InputStream is = NativeLibLoader.class.getResourceAsStream("/libringrtc.so"); + Path target = Files.createTempFile("", ""); + Files.copy(is, target, StandardCopyOption.REPLACE_EXISTING); + System.load(target.toString()); + } +} diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 2a8ed667..b6a141fe 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -24,6 +24,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.53" @@ -86,6 +95,25 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "cbindgen" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e3973b165dc0f435831a9e426de67e894de532754ff7a3f307c03ee5dec7dc" +dependencies = [ + "clap", + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml", +] + [[package]] name = "cc" version = "1.0.72" @@ -119,6 +147,21 @@ dependencies = [ "generic-array", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "combine" version = "4.6.3" @@ -836,6 +879,7 @@ dependencies = [ "anyhow", "base64", "bytes", + "cbindgen", "env_logger", "futures", "hex", @@ -987,6 +1031,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "subtle" version = "2.4.1" @@ -1039,6 +1089,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.30" @@ -1120,6 +1179,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "unicode-xid" version = "0.2.2" @@ -1160,6 +1225,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 765cf0a9..05b20d35 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -13,6 +13,7 @@ license = "AGPL-3.0-only" [lib] crate_type = ["cdylib", "staticlib", "lib"] +path = "src/lib.rs" [[bin]] name = "cli" @@ -89,6 +90,7 @@ required-features = ["sim"] jni = { version = "0.19.0", default-features = false } [build-dependencies] +cbindgen = "0.20.0" prost-build = { version = "0.8" } [dev-dependencies] diff --git a/src/rust/build.rs b/src/rust/build.rs index 9fc1c783..cbec362b 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -21,6 +21,15 @@ fn build_protos() { } fn main() { + if cfg!(feature = "java") { + let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + cbindgen::Builder::new() + .with_crate(crate_dir) + .with_language(cbindgen::Language::C) + .generate() + .expect("uunable to generate bindings") + .write_to_file("tringlib.h"); + } let target = env::var("TARGET").unwrap(); let profile = env::var("PROFILE").unwrap(); let out_dir = env::var("OUTPUT_DIR"); diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index df7e51cb..6009d608 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -57,6 +57,7 @@ pub mod protobuf; #[cfg(any(target_os = "android", feature = "check-all"))] /// Android specific implementation. +/// cbindgen:ignore mod android { #[macro_use] mod jni_util; @@ -75,6 +76,7 @@ mod android { #[cfg(any(target_os = "ios", feature = "check-all"))] /// iOS specific implementation. +/// cbindgen:ignore mod ios { mod api { pub mod call_manager_interface; @@ -91,6 +93,10 @@ pub mod electron; #[cfg(feature = "native")] pub mod native; +#[cfg(feature = "java")] +mod java { +} + /// Foreign Function Interface (FFI) to WebRTC C++ library. pub mod webrtc { pub mod arc; @@ -145,3 +151,4 @@ pub mod sim { pub mod simnet { pub mod router; } + From 49d78e33b42f15157b36306283218946ce04cc59 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 25 Sep 2022 21:59:40 +0200 Subject: [PATCH 03/74] Add first Java function to init logging --- .../tring/NativeLibLoader.java | 2 +- .../io/privacyresearch/tring/TringBridge.java | 32 +++++++++++++++++++ src/rust/Cargo.toml | 1 + src/rust/build.rs | 2 +- src/rust/src/java/java.rs | 26 +++++++++++++++ src/rust/src/lib.rs | 3 +- 6 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java create mode 100644 src/rust/src/java/java.rs diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java index 4a58cdd0..bde28eab 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java @@ -7,7 +7,7 @@ import java.nio.file.StandardCopyOption; public class NativeLibLoader { - + public static void loadLibrary() throws IOException { InputStream is = NativeLibLoader.class.getResourceAsStream("/libringrtc.so"); Path target = Files.createTempFile("", ""); diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java new file mode 100644 index 00000000..305187b9 --- /dev/null +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java @@ -0,0 +1,32 @@ +package io.privacyresearch.tring; + +import io.privacyresearch.tring.tringlib_h; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * + * @author johan + */ +public class TringBridge { + + private boolean nativeSupport = false; + + public TringBridge() { + + } + + public void init() { + try { + NativeLibLoader.loadLibrary(); + tringlib_h.initRingRTC(); + nativeSupport = true; + } catch (IOException ex) { + Logger.getLogger(TringBridge.class.getName()).log(Level.SEVERE, null, ex); + } + System.err.println("TringBridge init done, native support = "+nativeSupport); + } + +} diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 05b20d35..498282d8 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -51,6 +51,7 @@ subtle = { version = "2.3.0" } thiserror = { version = "1.0.20" } tokio = { version = "1.13.0", features = ["rt-multi-thread", "time"] } x25519-dalek = { version = "1.1" } +env_logger = { version = "0.8.1" } # Optional, needed by the 'sim' feature rand_chacha = { version = "0.2", optional = true } diff --git a/src/rust/build.rs b/src/rust/build.rs index cbec362b..a59237d1 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("uunable to generate bindings") + .expect("unable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs new file mode 100644 index 00000000..1ced794f --- /dev/null +++ b/src/rust/src/java/java.rs @@ -0,0 +1,26 @@ +use crate::webrtc::logging; + +fn init_logging() { + env_logger::builder() + .filter(None, log::LevelFilter::Debug) + .init(); + println!("LOGINIT done"); + // let is_first_time_initializing_logger = log::set_logger(&LOG).is_ok(); + let is_first_time_initializing_logger = true; + println!("EXTRALOG? {}", is_first_time_initializing_logger); + if is_first_time_initializing_logger { + // log::set_max_level(log::LevelFilter::Debug); + logging::set_logger(log::LevelFilter::Warn); + println!("EXTRALOG? yes"); + } + // logging::set_logger(log::LevelFilter::Trace); + info!("INFO logging enabled"); +} + +#[no_mangle] +pub unsafe extern "C" fn initRingRTC() -> i64 { + println!("Initialize RingRTC, init logging"); + init_logging(); + info!("Initialized RingRTC, using logging"); + 1 +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 6009d608..29385260 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -94,7 +94,8 @@ pub mod electron; pub mod native; #[cfg(feature = "java")] -mod java { +pub mod java { + pub mod java; } /// Foreign Function Interface (FFI) to WebRTC C++ library. From f155f35b97b95c86815b2240c2d6121d45637156 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 26 Sep 2022 10:28:07 +0200 Subject: [PATCH 04/74] build 0.0.1 version of jar copy native lib from correct location catch Throwable instead of Exception (as we also want to catch Link errors) --- bin/build-java | 4 ++-- src/java/tring/pom.xml | 2 +- .../src/main/java/io/privacyresearch/tring/TringBridge.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/build-java b/bin/build-java index 9e6f2088..5ea5ccd0 100755 --- a/bin/build-java +++ b/bin/build-java @@ -141,10 +141,10 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" elif [ $DEFAULT_PLATFORM = "linux" ] then mkdir -p ../java/build/linux - cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/tring/src/main/resources/libringrtc.so + cp -f target/${BUILD_TYPE}/libringrtc.so ../java/tring/src/main/resources/libringrtc.so cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/build/linux/libringrtc-"${TARGET_ARCH}".java fi - ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring -l ringrtc tringlib.h + ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h cd ../java/tring mvn clean install ) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index d99e8fb5..64ffad0f 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.1-SNAPSHOT + 0.0.1 jar UTF-8 diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java index 305187b9..eacbadb9 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java @@ -23,7 +23,7 @@ public void init() { NativeLibLoader.loadLibrary(); tringlib_h.initRingRTC(); nativeSupport = true; - } catch (IOException ex) { + } catch (Throwable ex) { Logger.getLogger(TringBridge.class.getName()).log(Level.SEVERE, null, ex); } System.err.println("TringBridge init done, native support = "+nativeSupport); From b8bbb92cd4af6e4e6a3ddf8014f964209634dd46 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 26 Sep 2022 19:15:19 +0200 Subject: [PATCH 05/74] bump pom and add enable-preview (required by NetBeans IDE) --- src/java/tring/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 64ffad0f..5067076c 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.1 + 0.0.2-SNAPSHOT jar UTF-8 @@ -18,7 +18,7 @@ 3.8.1 - --enable-preview + --enable-preview From 6e575c06bd682d5677fc46be3ed98f4ab15dbd3f Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 26 Sep 2022 21:27:29 +0200 Subject: [PATCH 06/74] add more functionality. Implement basic types for bridging Java and Rust. --- .../io/privacyresearch/tring/TringBridge.java | 87 +++- src/rust/build.rs | 2 +- src/rust/src/java/java.rs | 371 +++++++++++++++++- src/rust/src/lib.rs | 3 +- 4 files changed, 441 insertions(+), 22 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java index eacbadb9..19eb9598 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java @@ -1,32 +1,81 @@ package io.privacyresearch.tring; -import io.privacyresearch.tring.tringlib_h; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.MemorySession; +import java.lang.foreign.ValueLayout; - -/** - * - * @author johan - */ public class TringBridge { - private boolean nativeSupport = false; - - public TringBridge() { - - } - - public void init() { + private static boolean nativeSupport = false; + private static long nativeVersion = 0; + + private MemorySession scope; + private long callEndpoint; + + static { try { NativeLibLoader.loadLibrary(); - tringlib_h.initRingRTC(); nativeSupport = true; + nativeVersion = tringlib_h.getVersion(); } catch (Throwable ex) { - Logger.getLogger(TringBridge.class.getName()).log(Level.SEVERE, null, ex); + System.err.println("No native RingRTC support: "); + ex.printStackTrace(); } - System.err.println("TringBridge init done, native support = "+nativeSupport); } + public static long getNativeVersion() { + return nativeVersion; + } + + public TringBridge() { + initiate(); + } + +// public void init() { +// try { +// NativeLibLoader.loadLibrary(); +// scope = MemorySession.openShared(); +// tringlib_h.initRingRTC(toJString(scope, "Hallo, wereld")); +// nativeSupport = true; +// } catch (Throwable ex) { +// Logger.getLogger(TringBridge.class.getName()).log(Level.SEVERE, null, ex); +// } +// System.err.println("TringBridge init done, native support = " + nativeSupport); +// } + + private void initiate() { + scope = MemorySession.openShared(); + tringlib_h.initRingRTC(toJString(scope, "Hello from Java")); + this.callEndpoint = tringlib_h.createCallEndpoint(); + } + + public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, + byte[] senderKey, byte[] receiverKey, byte[] opaque) { + int mediaType = 0; + long ageSec = 0; + tringlib_h.receivedOffer(callEndpoint, toJString(scope, peerId), callId, mediaType, senderDeviceId, + receiverDeviceId, toJByteArray(scope, senderKey), toJByteArray(scope, receiverKey), + toJByteArray(scope, opaque), + ageSec); + } + + static MemorySegment toJByteArray(MemorySession ms, byte[] bytes) { + MemorySegment answer = JByteArray.allocate(ms); + JString.len$set(answer, bytes.length); + MemorySegment byteBuffer = MemorySegment.allocateNative(bytes.length, ms); + MemorySegment.copy(bytes, 0, byteBuffer, ValueLayout.JAVA_BYTE, 0, bytes.length); + JString.buff$set(answer, byteBuffer.address()); + return answer; + } + + static MemorySegment toJString(MemorySession ms, String src) { + MemorySegment answer = JString.allocate(ms); + byte[] bytes = src.getBytes(); + JString.len$set(answer, bytes.length); + MemorySegment byteBuffer = MemorySegment.allocateNative(bytes.length, ms); + MemorySegment.copy(bytes, 0, byteBuffer, ValueLayout.JAVA_BYTE, 0, bytes.length); + JString.buff$set(answer, byteBuffer.address()); + return answer; + } + } diff --git a/src/rust/build.rs b/src/rust/build.rs index a59237d1..cbec362b 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("unable to generate bindings") + .expect("uunable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 1ced794f..59118432 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -1,4 +1,33 @@ +use std::collections::HashMap; + +use std::sync::atomic::AtomicBool; +use std::sync::mpsc::{channel, Sender}; +use std::sync::{Arc, Mutex}; +use std::time::Duration; + +use crate::common::{CallId, CallMediaType, DeviceId, Result}; +use crate::core::call_manager::CallManager; +use crate::core::group_call; +use crate::core::group_call::{GroupId, SignalingMessageUrgency}; +use crate::core::signaling; +use crate::core::util::{ptr_as_mut}; + +use crate::java::jtypes::{JString,JByteArray}; + +use crate::lite::http; +use crate::lite::sfu::{UserId}; +use crate::native::{CallState,CallStateHandler,GroupUpdate,GroupUpdateHandler,NativePlatform,PeerId,SignalingSender,}; use crate::webrtc::logging; +use crate::webrtc::media::{ + VideoFrame, VideoSink +}; + +use crate::webrtc::peer_connection::AudioLevel; + +use crate::webrtc::peer_connection_factory::{ + self as pcf, PeerConnectionFactory +}; +use crate::webrtc::peer_connection_observer::NetworkRoute; fn init_logging() { env_logger::builder() @@ -17,10 +46,350 @@ fn init_logging() { info!("INFO logging enabled"); } +// When the Java layer processes events, we want everything to go through a common queue that +// combines all the things we want to "push" to it. +pub enum Event { + // The JavaScript should send the following signaling message to the given + // PeerId in context of the given CallId. If the DeviceId is None, then + // broadcast to all devices of that PeerId. + SendSignaling(PeerId, Option, CallId, signaling::Message), + // The JavaScript should send the following opaque call message to the + // given recipient UUID. + SendCallMessage { + recipient_uuid: UserId, + message: Vec, + urgency: group_call::SignalingMessageUrgency, + }, + // The JavaScript should send the following opaque call message to all + // other members of the given group + SendCallMessageToGroup { + group_id: GroupId, + message: Vec, + urgency: group_call::SignalingMessageUrgency, + }, + // The call with the given remote PeerId has changed state. + // We assume only one call per remote PeerId at a time. + CallState(PeerId, CallId, CallState), + // The state of the remote video (whether enabled or not) changed. + // Like call state, we ID the call by PeerId and assume there is only one. + RemoteVideoStateChange(PeerId, bool), + // Whether the remote is sharing its screen or not changed. + // Like call state, we ID the call by PeerId and assume there is only one. + RemoteSharingScreenChange(PeerId, bool), + // The group call has an update. + GroupUpdate(GroupUpdate), + // JavaScript should initiate an HTTP request. + SendHttpRequest { + request_id: u32, + request: http::Request, + }, + // The network route changed for a 1:1 call + NetworkRouteChange(PeerId, NetworkRoute), + AudioLevels { + peer_id: PeerId, + captured_level: AudioLevel, + received_level: AudioLevel, + }, +} + +/// Wraps a [`std::sync::mpsc::Sender`] with a callback to report new events. +#[derive(Clone)] +struct EventReporter { + sender: Sender, + report: Arc, +} + +impl EventReporter { + fn new(sender: Sender, report: impl Fn() + Send + Sync + 'static) -> Self { + Self { + sender, + report: Arc::new(report), + } + } + + fn send(&self, event: Event) -> Result<()> { + self.sender.send(event)?; + self.report(); + Ok(()) + } + + fn report(&self) { + (self.report)(); + } +} + +impl SignalingSender for EventReporter { + fn send_signaling( + &self, + recipient_id: &str, + call_id: CallId, + receiver_device_id: Option, + msg: signaling::Message, + ) -> Result<()> { + self.send(Event::SendSignaling( + recipient_id.to_string(), + receiver_device_id, + call_id, + msg, + ))?; + Ok(()) + } + + fn send_call_message( + &self, + recipient_uuid: UserId, + message: Vec, + urgency: SignalingMessageUrgency, + ) -> Result<()> { + self.send(Event::SendCallMessage { + recipient_uuid, + message, + urgency, + })?; + Ok(()) + } + + fn send_call_message_to_group( + &self, + group_id: GroupId, + message: Vec, + urgency: group_call::SignalingMessageUrgency, + ) -> Result<()> { + self.send(Event::SendCallMessageToGroup { + group_id, + message, + urgency, + })?; + Ok(()) + } +} + +impl CallStateHandler for EventReporter { + fn handle_call_state( + &self, + remote_peer_id: &str, + call_id: CallId, + call_state: CallState, + ) -> Result<()> { + self.send(Event::CallState( + remote_peer_id.to_string(), + call_id, + call_state, + ))?; + Ok(()) + } + + fn handle_network_route( + &self, + remote_peer_id: &str, + network_route: NetworkRoute, + ) -> Result<()> { + self.send(Event::NetworkRouteChange( + remote_peer_id.to_string(), + network_route, + ))?; + Ok(()) + } + + fn handle_remote_video_state(&self, remote_peer_id: &str, enabled: bool) -> Result<()> { + self.send(Event::RemoteVideoStateChange( + remote_peer_id.to_string(), + enabled, + ))?; + Ok(()) + } + + fn handle_remote_sharing_screen(&self, remote_peer_id: &str, enabled: bool) -> Result<()> { + self.send(Event::RemoteSharingScreenChange( + remote_peer_id.to_string(), + enabled, + ))?; + Ok(()) + } + + fn handle_audio_levels( + &self, + remote_peer_id: &str, + captured_level: AudioLevel, + received_level: AudioLevel, + ) -> Result<()> { + self.send(Event::AudioLevels { + peer_id: remote_peer_id.to_string(), + captured_level, + received_level, + })?; + Ok(()) + } +} + + +impl http::Delegate for EventReporter { + fn send_request(&self, request_id: u32, request: http::Request) { + let _ = self.send(Event::SendHttpRequest { + request_id, + request, + }); + } +} + +impl GroupUpdateHandler for EventReporter { + fn handle_group_update(&self, update: GroupUpdate) -> Result<()> { + self.send(Event::GroupUpdate(update))?; + Ok(()) + } +} + +pub struct CallEndpoint { + call_manager: CallManager, +} + +impl CallEndpoint { + fn new<'a>( + use_new_audio_device_module: bool, + ) -> Result { + // Relevant for both group calls and 1:1 calls + let (events_sender, _events_receiver) = channel::(); + let peer_connection_factory = PeerConnectionFactory::new(pcf::Config { + use_new_audio_device_module, + ..Default::default() + })?; + let outgoing_audio_track = peer_connection_factory.create_outgoing_audio_track()?; + outgoing_audio_track.set_enabled(false); + let outgoing_video_source = peer_connection_factory.create_outgoing_video_source()?; + let outgoing_video_track = + peer_connection_factory.create_outgoing_video_track(&outgoing_video_source)?; + outgoing_video_track.set_enabled(false); + let incoming_video_sink = Box::new(LastFramesVideoSink::default()); + + let event_reported = Arc::new(AtomicBool::new(false)); + + // let event_reporter = EventReporter::new(startCallback, answerCallback, iceUpdateCallback, events_sender, move || { + let event_reporter = EventReporter::new(events_sender, move || { + info!("[JV] EVENT_REPORTER, NYI"); + if event_reported.swap(true, std::sync::atomic::Ordering::Relaxed) { + return; + } + }); + // Only relevant for 1:1 calls + let signaling_sender = Box::new(event_reporter.clone()); + let should_assume_messages_sent = false; // Use async notification from app to send next message. + let state_handler = Box::new(event_reporter.clone()); + + // Only relevant for group calls + let http_client = http::DelegatingClient::new(event_reporter.clone()); + let group_handler = Box::new(event_reporter); + + let platform = NativePlatform::new( + peer_connection_factory.clone(), + signaling_sender, + should_assume_messages_sent, + state_handler, + group_handler, + ); + + let call_manager = CallManager::new(platform, http_client)?; + Ok(Self { + call_manager, + }) + } +} + +#[derive(Clone, Default)] +struct LastFramesVideoSink { + last_frame_by_track_id: Arc>>, +} + +impl VideoSink for LastFramesVideoSink { + fn on_video_frame(&self, track_id: u32, frame: VideoFrame) { + self.last_frame_by_track_id + .lock() + .unwrap() + .insert(track_id, frame); + } + + fn box_clone(&self) -> Box { + Box::new(self.clone()) + } +} + +impl LastFramesVideoSink { + fn pop(&self, track_id: u32) -> Option { + self.last_frame_by_track_id + .lock() + .unwrap() + .remove(&track_id) + } + + fn clear(&self) { + self.last_frame_by_track_id.lock().unwrap().clear(); + } +} + + #[no_mangle] -pub unsafe extern "C" fn initRingRTC() -> i64 { +pub unsafe extern "C" fn initRingRTC(ts: JString) -> i64 { println!("Initialize RingRTC, init logging"); init_logging(); + println!("Initialize RingRTC, init logging done"); +println!("Ready to print {:?}", ts); + let txt = ts.toString(); + info!("Got text: {}", txt); info!("Initialized RingRTC, using logging"); 1 } + +fn create_call_endpoint(audio: bool, + ) -> Result<*mut CallEndpoint> { + let call_endpoint = CallEndpoint::new(audio).unwrap(); + let call_endpoint_box = Box::new(call_endpoint); + Ok(Box::into_raw(call_endpoint_box)) +} + +#[no_mangle] +pub unsafe extern "C" fn getVersion() -> i64 { + 1 +} + +#[no_mangle] +pub unsafe extern "C" fn createCallEndpoint() -> i64 { + let answer: i64 = match create_call_endpoint(false) { + Ok(v) => v as i64, + Err(e) => { + info!("Error creating callEndpoint: {}", e); + 0 + } + }; + info!("[tring] CallEndpoint created at {}", answer); + answer +} + +#[no_mangle] +pub unsafe extern "C" fn receivedOffer(endpoint: i64, peerId: JString, call_id: u64, + offer_type:i32, sender_device_id:u32, receiver_device_id:u32, + sender_key: JByteArray, receiver_key: JByteArray, opaque: JByteArray, age_sec: u64) -> i64 { + let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + let peer_id = JString::from(peerId); + let call_id = CallId::new(call_id); + let call_media_type = match offer_type { + 1 => CallMediaType::Video, + _ => CallMediaType::Audio, // TODO: Do something better. Default matches are evil. + }; + let offer = signaling::Offer::new(call_media_type, opaque.toVecU8()).unwrap(); + callendpoint.call_manager.received_offer( + peer_id.toString(), + call_id, + signaling::ReceivedOffer { + offer, + age: Duration::from_secs(age_sec), + sender_device_id, + receiver_device_id, + // A Java desktop client cannot be the primary device. + receiver_device_is_primary: false, + sender_identity_key: sender_key.toVecU8(), + receiver_identity_key: receiver_key.toVecU8(), + }, + ); + + + 1 +} diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 29385260..1453e10a 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -95,7 +95,8 @@ pub mod native; #[cfg(feature = "java")] pub mod java { - pub mod java; + mod java; + mod jtypes; } /// Foreign Function Interface (FFI) to WebRTC C++ library. From 3795e5187c135c5b1c0d1409e420748c0abc94fe Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 26 Sep 2022 21:29:04 +0200 Subject: [PATCH 07/74] add java types --- src/rust/src/java/jtypes.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/rust/src/java/jtypes.rs diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs new file mode 100644 index 00000000..17f1dc48 --- /dev/null +++ b/src/rust/src/java/jtypes.rs @@ -0,0 +1,32 @@ +use core::slice; +use crate::native::PeerId; + +#[repr(C)] +#[derive(Debug)] +pub struct JString { + len: usize, + buff: *mut u8, +} + + +impl JString { + pub fn toString(&self) -> String { + let answer = unsafe { String::from_raw_parts(self.buff, self.len, self.len) }; + answer + } +} + +#[repr(C)] +#[derive(Debug)] +pub struct JByteArray { + len: usize, + buff: *mut u8, +} + + +impl JByteArray { + pub fn toVecU8(&self) -> Vec { + let answer = unsafe { slice::from_raw_parts(self.buff, self.len).to_vec() }; + answer + } +} From f9af9e55618041a2bb7ea29834bed07b0ef4496e Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Tue, 27 Sep 2022 21:59:45 +0200 Subject: [PATCH 08/74] Add more callback API's --- .../io/privacyresearch/tring/TringApi.java | 13 ++ .../io/privacyresearch/tring/TringBridge.java | 115 +++++++++-- src/rust/build.rs | 2 +- src/rust/src/common/mod.rs | 1 + src/rust/src/java/java.rs | 194 ++++++++++++++++-- src/rust/src/java/jtypes.rs | 54 ++++- 6 files changed, 335 insertions(+), 44 deletions(-) create mode 100644 src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java new file mode 100644 index 00000000..73eada04 --- /dev/null +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java @@ -0,0 +1,13 @@ +package io.privacyresearch.tring; + +/** + * + * @author johan + */ +public interface TringApi { + + void statusCallback(long callId, long peerId, int dir, int type); + + void answerCallback(byte[] opaque); + +} diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java index 19eb9598..0a9afd00 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java @@ -1,8 +1,11 @@ package io.privacyresearch.tring; +import java.lang.foreign.Addressable; +import java.lang.foreign.MemoryAddress; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; +import java.util.List; public class TringBridge { @@ -11,7 +14,9 @@ public class TringBridge { private MemorySession scope; private long callEndpoint; - + private final TringApi api; + private long activeCallId; + static { try { NativeLibLoader.loadLibrary(); @@ -27,46 +32,70 @@ public static long getNativeVersion() { return nativeVersion; } - public TringBridge() { + public TringBridge(TringApi api) { + this.api = api; initiate(); } -// public void init() { -// try { -// NativeLibLoader.loadLibrary(); -// scope = MemorySession.openShared(); -// tringlib_h.initRingRTC(toJString(scope, "Hallo, wereld")); -// nativeSupport = true; -// } catch (Throwable ex) { -// Logger.getLogger(TringBridge.class.getName()).log(Level.SEVERE, null, ex); -// } -// System.err.println("TringBridge init done, native support = " + nativeSupport); -// } - private void initiate() { scope = MemorySession.openShared(); tringlib_h.initRingRTC(toJString(scope, "Hello from Java")); - this.callEndpoint = tringlib_h.createCallEndpoint(); + this.callEndpoint = tringlib_h.createCallEndpoint(createStatusCallback(), + createAnswerCallback(), createIceUpdateCallback()); } public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, byte[] senderKey, byte[] receiverKey, byte[] opaque) { int mediaType = 0; long ageSec = 0; + this.activeCallId = callId; tringlib_h.receivedOffer(callEndpoint, toJString(scope, peerId), callId, mediaType, senderDeviceId, receiverDeviceId, toJByteArray(scope, senderKey), toJByteArray(scope, receiverKey), toJByteArray(scope, opaque), ageSec); } + public void setSelfUuid(String uuid) { + tringlib_h.setSelfUuid(callEndpoint, toJString(scope, uuid)); + } + + public void proceed(long callId) { + tringlib_h.proceedCall(callEndpoint, callId, 0, 0); + } + + public void receivedIce(long callId, int senderDeviceId, List ice) { + MemorySegment icePack = toJByteArray2D(scope, ice); + tringlib_h.receivedIce(callEndpoint, callId, senderDeviceId, icePack); + } + + static MemorySegment toJByteArray2D(MemorySession ms, List rows) { + MemorySegment answer = JByteArray2D.allocate(ms); + JByteArray2D.len$set(answer, rows.size()); + MemorySegment rowsSegment = JByteArray2D.buff$slice(answer); + for (int i = 0; i < rows.size(); i++) { + MemorySegment singleRowSegment = toJByteArray(ms, rows.get(i)); + MemorySegment row = rowsSegment.asSlice(16 * i, 16); + row.copyFrom(singleRowSegment); + } + return answer; + } + static MemorySegment toJByteArray(MemorySession ms, byte[] bytes) { MemorySegment answer = JByteArray.allocate(ms); - JString.len$set(answer, bytes.length); + JByteArray.len$set(answer, bytes.length); MemorySegment byteBuffer = MemorySegment.allocateNative(bytes.length, ms); MemorySegment.copy(bytes, 0, byteBuffer, ValueLayout.JAVA_BYTE, 0, bytes.length); - JString.buff$set(answer, byteBuffer.address()); + JByteArray.buff$set(answer, byteBuffer.address()); return answer; } + + static byte[] fromJByteArray(MemorySession ms, MemorySegment jByteArray) { + long len = JByteArray.len$get(jByteArray); + MemoryAddress pointer = JByteArray.buff$get(jByteArray); + MemorySegment byteSegment = JByteArray.ofAddress(pointer, ms); + byte[] data = byteSegment.toArray(ValueLayout.JAVA_BYTE); + return data; + } static MemorySegment toJString(MemorySession ms, String src) { MemorySegment answer = JString.allocate(ms); @@ -78,4 +107,56 @@ static MemorySegment toJString(MemorySession ms, String src) { return answer; } + Addressable createStatusCallback() { + StatusCallbackImpl sci = new StatusCallbackImpl(); + MemorySegment seg = createCallEndpoint$statusCallback.allocate(sci, scope); + return seg.address(); + } + + class StatusCallbackImpl implements createCallEndpoint$statusCallback { + @Override + public void apply(MemorySegment callId, long _x1, int direction, int type) { + long id = CallId.id$get(callId); + api.statusCallback(id, _x1, direction, type); + } + } + + Addressable createAnswerCallback() { + AnswerCallbackImpl sci = new AnswerCallbackImpl(); + MemorySegment seg = createCallEndpoint$answerCallback.allocate(sci, scope); + return seg.address(); + } + + class AnswerCallbackImpl implements createCallEndpoint$answerCallback { + @Override + public void apply(MemorySegment opaque) { + System.err.println("TRINGBRIDGE, send answer!"); + byte[] bytes = fromJByteArray(scope, opaque); + System.err.println("TRING, bytes to send = "+java.util.Arrays.toString(bytes)); + api.answerCallback(bytes); + System.err.println("TRING, answer sent"); + sendAck(); + System.err.println("TRING, ack sent"); + } + } + + Addressable createIceUpdateCallback() { + IceUpdateCallbackImpl sci = new IceUpdateCallbackImpl(); + MemorySegment seg = createCallEndpoint$iceUpdateCallback.allocate(sci, scope); + return seg.address(); + } + + class IceUpdateCallbackImpl implements createCallEndpoint$iceUpdateCallback { + @Override + public void apply(MemorySegment opaque) { + System.err.println("TRINGBRIDGE, iceUpdate!"); + + } + } + + void sendAck() { + MemorySegment callid = MemorySegment.allocateNative(8, scope); + callid.set(ValueLayout.JAVA_LONG, 0l, activeCallId); + tringlib_h.signalMessageSent(callEndpoint, callid); + } } diff --git a/src/rust/build.rs b/src/rust/build.rs index cbec362b..a59237d1 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("uunable to generate bindings") + .expect("unable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/common/mod.rs b/src/rust/src/common/mod.rs index 1cfd1ad6..0d271d36 100644 --- a/src/rust/src/common/mod.rs +++ b/src/rust/src/common/mod.rs @@ -16,6 +16,7 @@ pub type Result = std::result::Result; /// Unique call identification number. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[repr(C)] pub struct CallId { id: u64, } diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 59118432..667fe7a8 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -5,27 +5,28 @@ use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; use std::time::Duration; -use crate::common::{CallId, CallMediaType, DeviceId, Result}; +use crate::common::{CallDirection, CallId, CallMediaType, DeviceId, Result}; +use crate::core::bandwidth_mode::BandwidthMode; use crate::core::call_manager::CallManager; use crate::core::group_call; use crate::core::group_call::{GroupId, SignalingMessageUrgency}; use crate::core::signaling; use crate::core::util::{ptr_as_mut}; -use crate::java::jtypes::{JString,JByteArray}; +use crate::java::jtypes::{JString,JByteArray,JByteArray2D}; use crate::lite::http; use crate::lite::sfu::{UserId}; -use crate::native::{CallState,CallStateHandler,GroupUpdate,GroupUpdateHandler,NativePlatform,PeerId,SignalingSender,}; +use crate::native::{CallState,CallStateHandler,GroupUpdate,GroupUpdateHandler,NativeCallContext,NativePlatform,PeerId,SignalingSender,}; use crate::webrtc::logging; use crate::webrtc::media::{ - VideoFrame, VideoSink + AudioTrack, VideoFrame, VideoSink, VideoSource, VideoTrack, }; use crate::webrtc::peer_connection::AudioLevel; use crate::webrtc::peer_connection_factory::{ - self as pcf, PeerConnectionFactory + self as pcf, IceServer, PeerConnectionFactory }; use crate::webrtc::peer_connection_observer::NetworkRoute; @@ -94,22 +95,67 @@ pub enum Event { /// Wraps a [`std::sync::mpsc::Sender`] with a callback to report new events. #[derive(Clone)] +#[repr(C)] +#[allow(non_snake_case)] struct EventReporter { + pub statusCallback: unsafe extern "C" fn(CallId, u64, CallDirection, CallMediaType), + pub answerCallback: unsafe extern "C" fn(JByteArray), + pub iceUpdateCallback: unsafe extern "C" fn(JByteArray2D), sender: Sender, report: Arc, } impl EventReporter { - fn new(sender: Sender, report: impl Fn() + Send + Sync + 'static) -> Self { + fn new(statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), + answerCallback: extern "C" fn(JByteArray), + iceUpdateCallback: extern "C" fn(JByteArray2D), + sender: Sender, report: impl Fn() + Send + Sync + 'static) -> Self { Self { + statusCallback, + answerCallback, + iceUpdateCallback, sender, report: Arc::new(report), } } fn send(&self, event: Event) -> Result<()> { - self.sender.send(event)?; - self.report(); + match event { + Event::SendSignaling(_peer_id, _maybe_device_id, _call_id, signal) => { + info!("[JV] SendSignalingEvent"); + match signal { + signaling::Message::Answer(answer) => { + info!("[JV] SendSignaling ANSWER Event"); + let op = JByteArray::new(answer.opaque); + unsafe { + (self.answerCallback)(op); + } + } +/* + signaling::Message::Ice(ice) => { + info!("[JV] SendSignaling ICE Event"); + let icepack: JByteArray2D = JByteArray2D::new(ice.candidates); + unsafe { + (self.iceUpdateCallback)(icepack); + } + } +*/ + _ => { + info!("[JV] unknownSendSignalingEvent WHICH IS WHAT WE NEED TO FIX NOW!"); + } + } + } + Event::CallState(_peer_id, call_id, CallState::Incoming(call_media_type)) => { + info!("[JV] CALLSTATEEVEMNT"); + unsafe { + (self.statusCallback)(call_id, 1,CallDirection::InComing, call_media_type); + } + } + _ => { + info!("[JV] unknownevent"); + } + }; + Ok(()) } @@ -171,6 +217,8 @@ impl CallStateHandler for EventReporter { call_id: CallId, call_state: CallState, ) -> Result<()> { +info!("[JV] CallStatehandler, invoke self.send"); + self.send(Event::CallState( remote_peer_id.to_string(), call_id, @@ -241,11 +289,25 @@ impl GroupUpdateHandler for EventReporter { pub struct CallEndpoint { call_manager: CallManager, + // This is what we use to control mute/not. + // It should probably be per-call, but for now it's easier to have only one. + outgoing_audio_track: AudioTrack, + // This is what we use to push video frames out. + outgoing_video_source: VideoSource, + // We only keep this around so we can pass it to PeerConnectionFactory::create_peer_connection + // via the NativeCallContext. + outgoing_video_track: VideoTrack, + // Boxed so we can pass it as a Box + incoming_video_sink: Box, + } impl CallEndpoint { fn new<'a>( use_new_audio_device_module: bool, + statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), + answerCallback: extern "C" fn(JByteArray), + iceUpdateCallback: extern "C" fn(JByteArray2D), ) -> Result { // Relevant for both group calls and 1:1 calls let (events_sender, _events_receiver) = channel::(); @@ -264,7 +326,7 @@ impl CallEndpoint { let event_reported = Arc::new(AtomicBool::new(false)); // let event_reporter = EventReporter::new(startCallback, answerCallback, iceUpdateCallback, events_sender, move || { - let event_reporter = EventReporter::new(events_sender, move || { + let event_reporter = EventReporter::new(statusCallback, answerCallback, iceUpdateCallback, events_sender, move || { info!("[JV] EVENT_REPORTER, NYI"); if event_reported.swap(true, std::sync::atomic::Ordering::Relaxed) { return; @@ -290,6 +352,10 @@ impl CallEndpoint { let call_manager = CallManager::new(platform, http_client)?; Ok(Self { call_manager, + outgoing_audio_track, + outgoing_video_source, + outgoing_video_track, + incoming_video_sink, }) } } @@ -332,27 +398,32 @@ pub unsafe extern "C" fn initRingRTC(ts: JString) -> i64 { init_logging(); println!("Initialize RingRTC, init logging done"); println!("Ready to print {:?}", ts); - let txt = ts.toString(); + let txt = ts.to_string(); info!("Got text: {}", txt); info!("Initialized RingRTC, using logging"); 1 } +#[no_mangle] +pub unsafe extern "C" fn getVersion() -> i64 { + 1 +} + fn create_call_endpoint(audio: bool, + statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), + answerCallback: extern "C" fn(JByteArray), + iceUpdateCallback: extern "C" fn(JByteArray2D), ) -> Result<*mut CallEndpoint> { - let call_endpoint = CallEndpoint::new(audio).unwrap(); + let call_endpoint = CallEndpoint::new(audio, statusCallback, answerCallback, iceUpdateCallback).unwrap(); let call_endpoint_box = Box::new(call_endpoint); Ok(Box::into_raw(call_endpoint_box)) } #[no_mangle] -pub unsafe extern "C" fn getVersion() -> i64 { - 1 -} - -#[no_mangle] -pub unsafe extern "C" fn createCallEndpoint() -> i64 { - let answer: i64 = match create_call_endpoint(false) { +pub unsafe extern "C" fn createCallEndpoint(statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), + answerCallback: extern "C" fn(JByteArray), + iceUpdateCallback: extern "C" fn(JByteArray2D)) -> i64 { + let answer: i64 = match create_call_endpoint(false, statusCallback, answerCallback, iceUpdateCallback) { Ok(v) => v as i64, Err(e) => { info!("Error creating callEndpoint: {}", e); @@ -363,6 +434,16 @@ pub unsafe extern "C" fn createCallEndpoint() -> i64 { answer } +#[no_mangle] +pub unsafe extern "C" fn setSelfUuid(endpoint: i64, ts: JString) -> i64 { + let txt = ts.to_string(); + info!("setSelfUuid to : {}", txt); + let uuid = txt.into_bytes(); + let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + callendpoint.call_manager.set_self_uuid(uuid); + 1 +} + #[no_mangle] pub unsafe extern "C" fn receivedOffer(endpoint: i64, peerId: JString, call_id: u64, offer_type:i32, sender_device_id:u32, receiver_device_id:u32, @@ -374,9 +455,9 @@ pub unsafe extern "C" fn receivedOffer(endpoint: i64, peerId: JString, call_id: 1 => CallMediaType::Video, _ => CallMediaType::Audio, // TODO: Do something better. Default matches are evil. }; - let offer = signaling::Offer::new(call_media_type, opaque.toVecU8()).unwrap(); + let offer = signaling::Offer::new(call_media_type, opaque.to_vec_u8()).unwrap(); callendpoint.call_manager.received_offer( - peer_id.toString(), + peer_id.to_string(), call_id, signaling::ReceivedOffer { offer, @@ -385,11 +466,80 @@ pub unsafe extern "C" fn receivedOffer(endpoint: i64, peerId: JString, call_id: receiver_device_id, // A Java desktop client cannot be the primary device. receiver_device_is_primary: false, - sender_identity_key: sender_key.toVecU8(), - receiver_identity_key: receiver_key.toVecU8(), + sender_identity_key: sender_key.to_vec_u8(), + receiver_identity_key: receiver_key.to_vec_u8(), }, ); 1 } + +#[no_mangle] +pub unsafe extern "C" fn proceedCall(endpoint: i64, call_id: u64, bandwidth_mode: i32, audio_levels_interval_millis:i32) -> i64 { + info!("Proceeding with call"); + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + let call_id = CallId::from(call_id); + let ice_server = IceServer::new(String::from("iceuser"), String::from("icepwd"), Vec::new()); + let context = NativeCallContext::new( + false, + ice_server, + endpoint.outgoing_audio_track.clone(), + endpoint.outgoing_video_track.clone(), + endpoint.incoming_video_sink.clone(), + ); + let audio_levels_interval = if audio_levels_interval_millis <= 0 { + None + } else { + Some(Duration::from_millis(audio_levels_interval_millis as u64)) + }; + endpoint.call_manager.proceed( + call_id, + context, + BandwidthMode::from_i32(bandwidth_mode), + audio_levels_interval); + + 147 +} + +#[no_mangle] +pub unsafe extern "C" fn receivedIce(endpoint: i64, call_id: u64, sender_device_id: DeviceId, icepack: JByteArray2D) { + info!("JavaRing, received_ice with length = {}", icepack.len ); + let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("Received offer, endpoint = {:?}", endpoint); + let call_id = CallId::from(call_id); + let mut ice_candidates = Vec::new(); + for j in 0..icepack.len { + let row = &icepack.buff[j]; + let opaque = row.to_vec_u8(); + ice_candidates.push(signaling::IceCandidate::new(opaque)); + } + callendpoint.call_manager.received_ice( + call_id, + signaling::ReceivedIce { + ice: signaling::Ice { + candidates: ice_candidates, + }, + sender_device_id, + }, + ); +} + + +#[no_mangle] +pub unsafe extern "C" fn acceptCall(endpoint: i64, call_id: u64) -> i64 { + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + let call_id = CallId::from(call_id); + endpoint.call_manager.accept_call(call_id); + 573 +} + +#[no_mangle] +pub unsafe extern "C" fn signalMessageSent(endpoint: i64, call_id: CallId) -> i64 { + let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("Received signalmessagesent, endpoint = {:?}", endpoint); + callendpoint.call_manager.message_sent(call_id); + 135 +} + + diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index 17f1dc48..87f84355 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -1,5 +1,6 @@ use core::slice; -use crate::native::PeerId; +use crate::core::signaling; + #[repr(C)] #[derive(Debug)] @@ -10,14 +11,14 @@ pub struct JString { impl JString { - pub fn toString(&self) -> String { + pub fn to_string(&self) -> String { let answer = unsafe { String::from_raw_parts(self.buff, self.len, self.len) }; answer } } #[repr(C)] -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct JByteArray { len: usize, buff: *mut u8, @@ -25,8 +26,53 @@ pub struct JByteArray { impl JByteArray { - pub fn toVecU8(&self) -> Vec { + pub fn new(mut vector: Vec) -> Self { + let buffer = vector.as_mut_ptr(); + JByteArray{len: vector.len(), buff: buffer} + } + + pub fn to_vec_u8(&self) -> Vec { let answer = unsafe { slice::from_raw_parts(self.buff, self.len).to_vec() }; answer } + + pub fn empty() -> Self { + let bar = Vec::new().as_mut_ptr(); + JByteArray{len: 0, buff: bar} + } + +/* + pub fn from_data(data: *mut u8, len: usize) -> Self { + JByteArray{len: len, buff: data} + } +*/ + +} + +#[repr(C)] +#[derive(Debug)] +pub struct JByteArray2D { + pub len: usize, + pub buff: [JByteArray;32], +} + +impl JByteArray2D { +/* + pub fn new(vector: Vec) -> Self { + let vlen = vector.len(); + // let mut myrows = [Opaque::empty(); 25]; + let mut myrows: [JByteArray; 32] = [JByteArray::empty(); 32]; + for i in 0..25 { + if (i < vlen) { + myrows[i] = JByteArray::from_data(vector[i].opaque.as_ptr(), vector[i].opaque.len()); + } else { + myrows[i] = JByteArray::new(Vec::new()); + } + } + JByteArray2D { + len: vlen, + buff: myrows, + } + } +*/ } From 3775d15ceb6b27570afb21d900aef5a7aa6b3003 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Wed, 28 Sep 2022 18:35:45 +0200 Subject: [PATCH 09/74] implement flow until ConnectedBeforeAccepted --- .../io/privacyresearch/tring/TringApi.java | 4 + .../io/privacyresearch/tring/TringBridge.java | 88 +++++++++++++++++-- src/rust/build.rs | 2 +- src/rust/src/java/java.rs | 29 +++--- src/rust/src/java/jtypes.rs | 83 +++++++++++++++-- 5 files changed, 176 insertions(+), 30 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java index 73eada04..42d09405 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java @@ -1,5 +1,7 @@ package io.privacyresearch.tring; +import java.util.List; + /** * * @author johan @@ -9,5 +11,7 @@ public interface TringApi { void statusCallback(long callId, long peerId, int dir, int type); void answerCallback(byte[] opaque); + + void iceUpdateCallback(List iceCandidates); } diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java index 0a9afd00..c10bf4e8 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java @@ -2,9 +2,13 @@ import java.lang.foreign.Addressable; import java.lang.foreign.MemoryAddress; +import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; +import static java.lang.foreign.ValueLayout.ADDRESS; +import java.lang.invoke.VarHandle; +import java.util.ArrayList; import java.util.List; public class TringBridge { @@ -89,11 +93,55 @@ static MemorySegment toJByteArray(MemorySession ms, byte[] bytes) { return answer; } + static byte[] fromJArrayByte(MemorySession ms, MemorySegment jArrayByte) { + int len = (int)JArrayByte.len$get(jArrayByte); + MemorySegment dataSegment = JArrayByte.data$slice(jArrayByte).asSlice(0, len); + byte[] destArr = new byte[len]; + MemorySegment dstSeq = MemorySegment.ofArray(destArr); + dstSeq.copyFrom(dataSegment); + return destArr; + } + static byte[] fromJByteArray(MemorySession ms, MemorySegment jByteArray) { long len = JByteArray.len$get(jByteArray); + System.err.println("Need to read byte array with "+len+" bytes"); + for (int j = 0; j < 16; j++) { + byte b = jByteArray.get(ValueLayout.JAVA_BYTE, j); + System.err.println("b["+j+"] = "+b); + } + //VarHandle buffHandle = JByteArray.$struct$LAYOUT.varHandle(long.class, MemoryLayout.PathElement.groupElement("buff")); + MemoryAddress pointer = JByteArray.buff$get(jByteArray); - MemorySegment byteSegment = JByteArray.ofAddress(pointer, ms); - byte[] data = byteSegment.toArray(ValueLayout.JAVA_BYTE); + System.err.println("pointer at "+ pointer.address()); +MemorySegment segment = MemorySegment.ofAddress(pointer, len, ms); +byte[] destArr = new byte[(int)len]; + MemorySegment dstSeq = MemorySegment.ofArray(destArr); + dstSeq.copyFrom(segment); + System.err.println("After copy, destArr = "+java.util.Arrays.toString(destArr)); + + + + for (int j = 0; j < len; j++) { + byte b = segment.get(ValueLayout.JAVA_BYTE, j); + System.err.println("Bb[" + j + "] = " + b); + + } + + + // MemoryAddress pointer = ptr.get(ValueLayout.ADDRESS, 0); + System.err.println("ptr = "+pointer+", val = " + pointer.toRawLongValue()); + System.err.println("ptr address = "+pointer.address()); + byte[] data = new byte[(int)len]; + for (int i =0; i < data.length; i++) { + data[i] = pointer.get(ValueLayout.JAVA_BYTE, i); + } + System.err.println("got data: "+java.util.Arrays.toString(data)); + byte p0 = pointer.address().get(ValueLayout.JAVA_BYTE, 0); + byte p1 = pointer.address().get(ValueLayout.JAVA_BYTE, 1); + byte p8 = pointer.address().get(ValueLayout.JAVA_BYTE, 8); + System.err.println("p0 = "+p0+", p1 = "+p1+", p8 = "+p8); +// MemorySegment byteSegment = JByteArray.ofAddress(pointer, ms); +// byte[] data = byteSegment.toArray(ValueLayout.JAVA_BYTE); return data; } @@ -131,7 +179,7 @@ class AnswerCallbackImpl implements createCallEndpoint$answerCallback { @Override public void apply(MemorySegment opaque) { System.err.println("TRINGBRIDGE, send answer!"); - byte[] bytes = fromJByteArray(scope, opaque); + byte[] bytes = fromJArrayByte(scope, opaque); System.err.println("TRING, bytes to send = "+java.util.Arrays.toString(bytes)); api.answerCallback(bytes); System.err.println("TRING, answer sent"); @@ -148,8 +196,38 @@ Addressable createIceUpdateCallback() { class IceUpdateCallbackImpl implements createCallEndpoint$iceUpdateCallback { @Override - public void apply(MemorySegment opaque) { - System.err.println("TRINGBRIDGE, iceUpdate!"); + public void apply(MemorySegment icePack) { + long length = JArrayByte2D.len$get(icePack); + System.err.println("IcePack has "+length+ " ice updates, address at "+icePack); + List iceCandidates = new ArrayList<>(); + MemorySegment allData = JArrayByte2D.data$slice(icePack); + long allSize = allData.byteSize(); + System.err.println("All size = " + allSize); + for (int i = 0; i < length; i++) { + int rowLength = (int) JByteArray.len$get(allData, i); + MemoryAddress rowData = JByteArray.buff$get(allData, i); + System.err.println("Got length for " + i + ": " + rowLength); + byte[] rowBytes = new byte[rowLength]; + MemorySegment destSegment = MemorySegment.ofArray(rowBytes); + MemorySegment rowSegment = MemorySegment.ofAddress(rowData, rowLength, scope); + destSegment.copyFrom(rowSegment); + System.err.println("ICbytes = " + java.util.Arrays.toString(rowBytes)); + iceCandidates.add(rowBytes); + } + +// MemorySegment rows = JArrayByte2D.data$slice(icePack); +// // MemorySegment rows = JArrayByte2D.buff$slice(icePack); +// for (int i = 0; i < length; i++) { +// MemorySegment row = rows.asSlice(16*i, 16); +// long bl = JArrayByte.len$get(row); +// MemorySegment byteSegment = JArrayByte.data$slice(row); +// byte[] rowByte = fromJArrayByte(scope, byteSegment); +// iceCandidates.add(rowByte); +// } + api.iceUpdateCallback(iceCandidates); + // waveCallManager.handleSendIceCandidates(activeCall, false, iceCandidates); + sendAck(); + System.err.println("TRINGBRIDGE, iceUpdate done!"); } } diff --git a/src/rust/build.rs b/src/rust/build.rs index a59237d1..cbec362b 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("unable to generate bindings") + .expect("uunable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 667fe7a8..2bce08a8 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -13,7 +13,7 @@ use crate::core::group_call::{GroupId, SignalingMessageUrgency}; use crate::core::signaling; use crate::core::util::{ptr_as_mut}; -use crate::java::jtypes::{JString,JByteArray,JByteArray2D}; +use crate::java::jtypes::{JString,JArrayByte,JByteArray,JArrayByte2D,JByteArray2D}; use crate::lite::http; use crate::lite::sfu::{UserId}; @@ -99,16 +99,16 @@ pub enum Event { #[allow(non_snake_case)] struct EventReporter { pub statusCallback: unsafe extern "C" fn(CallId, u64, CallDirection, CallMediaType), - pub answerCallback: unsafe extern "C" fn(JByteArray), - pub iceUpdateCallback: unsafe extern "C" fn(JByteArray2D), + pub answerCallback: unsafe extern "C" fn(JArrayByte), + pub iceUpdateCallback: unsafe extern "C" fn(JArrayByte2D), sender: Sender, report: Arc, } impl EventReporter { fn new(statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), - answerCallback: extern "C" fn(JByteArray), - iceUpdateCallback: extern "C" fn(JByteArray2D), + answerCallback: extern "C" fn(JArrayByte), + iceUpdateCallback: extern "C" fn(JArrayByte2D), sender: Sender, report: impl Fn() + Send + Sync + 'static) -> Self { Self { statusCallback, @@ -126,20 +126,18 @@ impl EventReporter { match signal { signaling::Message::Answer(answer) => { info!("[JV] SendSignaling ANSWER Event"); - let op = JByteArray::new(answer.opaque); + let op = JArrayByte::new(answer.opaque); unsafe { (self.answerCallback)(op); } } -/* signaling::Message::Ice(ice) => { info!("[JV] SendSignaling ICE Event"); - let icepack: JByteArray2D = JByteArray2D::new(ice.candidates); + let icepack: JArrayByte2D = JArrayByte2D::new(ice.candidates); unsafe { (self.iceUpdateCallback)(icepack); } } -*/ _ => { info!("[JV] unknownSendSignalingEvent WHICH IS WHAT WE NEED TO FIX NOW!"); } @@ -172,6 +170,7 @@ impl SignalingSender for EventReporter { receiver_device_id: Option, msg: signaling::Message, ) -> Result<()> { +info!("Need to send SIGNALING msg {:?}", msg); self.send(Event::SendSignaling( recipient_id.to_string(), receiver_device_id, @@ -306,8 +305,8 @@ impl CallEndpoint { fn new<'a>( use_new_audio_device_module: bool, statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), - answerCallback: extern "C" fn(JByteArray), - iceUpdateCallback: extern "C" fn(JByteArray2D), + answerCallback: extern "C" fn(JArrayByte), + iceUpdateCallback: extern "C" fn(JArrayByte2D), ) -> Result { // Relevant for both group calls and 1:1 calls let (events_sender, _events_receiver) = channel::(); @@ -411,8 +410,8 @@ pub unsafe extern "C" fn getVersion() -> i64 { fn create_call_endpoint(audio: bool, statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), - answerCallback: extern "C" fn(JByteArray), - iceUpdateCallback: extern "C" fn(JByteArray2D), + answerCallback: extern "C" fn(JArrayByte), + iceUpdateCallback: extern "C" fn(JArrayByte2D), ) -> Result<*mut CallEndpoint> { let call_endpoint = CallEndpoint::new(audio, statusCallback, answerCallback, iceUpdateCallback).unwrap(); let call_endpoint_box = Box::new(call_endpoint); @@ -421,8 +420,8 @@ fn create_call_endpoint(audio: bool, #[no_mangle] pub unsafe extern "C" fn createCallEndpoint(statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), - answerCallback: extern "C" fn(JByteArray), - iceUpdateCallback: extern "C" fn(JByteArray2D)) -> i64 { + answerCallback: extern "C" fn(JArrayByte), + iceUpdateCallback: extern "C" fn(JArrayByte2D)) -> i64 { let answer: i64 = match create_call_endpoint(false, statusCallback, answerCallback, iceUpdateCallback) { Ok(v) => v as i64, Err(e) => { diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index 87f84355..5557da16 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -1,5 +1,6 @@ use core::slice; use crate::core::signaling; +use std::fmt; #[repr(C)] @@ -16,18 +17,86 @@ impl JString { answer } } +#[repr(C)] +#[derive(Clone, Copy, Debug)] +pub struct JArrayByte { + pub len: usize, + pub data: [u8; 256], +} + +impl JArrayByte { + pub fn new(vector: Vec ) -> Self { + let vlen = vector.len(); + let mut vdata= [0; 256]; + for i in 0..vlen { + vdata[i] = vector[i]; + } + JArrayByte{len:vlen, data:vdata} + } + + pub fn empty() -> Self { + let data = [0;256]; + JArrayByte{len: 0, data: data} + } + +} + + +#[repr(C)] +#[derive(Debug)] +pub struct JArrayByte2D { + pub len: usize, + pub data: [JByteArray;25], +} + +impl JArrayByte2D { + pub fn new(vector: Vec) -> Self { + let vlen = vector.len(); + let mut myrows: [JByteArray; 25] = [JByteArray::empty(); 25]; + for i in 0..25 { + if (i < vlen) { + myrows[i] = JByteArray::from_data(vector[i].opaque.as_ptr(), vector[i].opaque.len()); + } else { + myrows[i] = JByteArray::new(Vec::new()); + } + } + +/* + let mut myrows: [JArrayByte; 2] = [JArrayByte::empty(); 2]; + for i in 0..2 { + if (i < vlen) { + myrows[i] = JArrayByte::new(vector[i].opaque.clone()); + } else { + myrows[i] = JArrayByte::new(Vec::new()); + } + } +*/ + JArrayByte2D { + len: vlen, + data: myrows, + } + } +} + #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct JByteArray { len: usize, - buff: *mut u8, + pub buff: *const u8, } +impl fmt::Display for JByteArray { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let address = &self.buff; + write!(f, "jByteArray with {} bytes at {:p}", self.len, self.buff) + } +} impl JByteArray { - pub fn new(mut vector: Vec) -> Self { - let buffer = vector.as_mut_ptr(); + pub fn new(vector: Vec) -> Self { + let slice = vector.as_slice(); + let buffer = slice.as_ptr(); JByteArray{len: vector.len(), buff: buffer} } @@ -37,15 +106,13 @@ impl JByteArray { } pub fn empty() -> Self { - let bar = Vec::new().as_mut_ptr(); + let bar = Vec::new().as_ptr(); JByteArray{len: 0, buff: bar} } -/* - pub fn from_data(data: *mut u8, len: usize) -> Self { + pub fn from_data(data: *const u8, len: usize) -> Self { JByteArray{len: len, buff: data} } -*/ } @@ -57,7 +124,6 @@ pub struct JByteArray2D { } impl JByteArray2D { -/* pub fn new(vector: Vec) -> Self { let vlen = vector.len(); // let mut myrows = [Opaque::empty(); 25]; @@ -74,5 +140,4 @@ impl JByteArray2D { buff: myrows, } } -*/ } From 0b91be8d068d311488d3675a97a6b26bc0296c04 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Wed, 28 Sep 2022 20:07:50 +0200 Subject: [PATCH 10/74] Works with accepting call. --- .../io/privacyresearch/tring/TringBridge.java | 4 +++ src/rust/build.rs | 2 +- src/rust/src/java/java.rs | 29 +++++++++++++++---- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java index c10bf4e8..d8c763d7 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java @@ -71,6 +71,10 @@ public void receivedIce(long callId, int senderDeviceId, List ice) { MemorySegment icePack = toJByteArray2D(scope, ice); tringlib_h.receivedIce(callEndpoint, callId, senderDeviceId, icePack); } + + public void acceptCall() { + tringlib_h.acceptCall(callEndpoint, activeCallId); + } static MemorySegment toJByteArray2D(MemorySession ms, List rows) { MemorySegment answer = JByteArray2D.allocate(ms); diff --git a/src/rust/build.rs b/src/rust/build.rs index cbec362b..a59237d1 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("uunable to generate bindings") + .expect("unable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 2bce08a8..9c0e8786 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -98,7 +98,7 @@ pub enum Event { #[repr(C)] #[allow(non_snake_case)] struct EventReporter { - pub statusCallback: unsafe extern "C" fn(CallId, u64, CallDirection, CallMediaType), + pub statusCallback: unsafe extern "C" fn(CallId, u64, i32, CallMediaType), pub answerCallback: unsafe extern "C" fn(JArrayByte), pub iceUpdateCallback: unsafe extern "C" fn(JArrayByte2D), sender: Sender, @@ -106,7 +106,7 @@ struct EventReporter { } impl EventReporter { - fn new(statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), + fn new(statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte2D), sender: Sender, report: impl Fn() + Send + Sync + 'static) -> Self { @@ -145,8 +145,25 @@ impl EventReporter { } Event::CallState(_peer_id, call_id, CallState::Incoming(call_media_type)) => { info!("[JV] CALLSTATEEVEMNT"); + let direction = 0; unsafe { - (self.statusCallback)(call_id, 1,CallDirection::InComing, call_media_type); + (self.statusCallback)(call_id, 1,direction, call_media_type); + } + } + Event::CallState(_peer_id, call_id, state) => { + info!("[JV] CallState changed"); + let (state_string, state_index) = match state { + CallState::Ringing => ("ringing", 1), + CallState::Connected => ("connected", 2), + CallState::Connecting => ("connecting", 3), + CallState::Concluded => ("Concluded", 4), + CallState::Incoming(_) => ("incoming", 5), + CallState::Outgoing(_) => ("outgoing", 6), + CallState::Ended(_) => ("ended", 7), + }; + info!("New state = {} and index = {}", state_string, state_index); + unsafe { + (self.statusCallback)(call_id, 1, 10*state_index, CallMediaType::Audio); } } _ => { @@ -304,7 +321,7 @@ pub struct CallEndpoint { impl CallEndpoint { fn new<'a>( use_new_audio_device_module: bool, - statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), + statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte2D), ) -> Result { @@ -409,7 +426,7 @@ pub unsafe extern "C" fn getVersion() -> i64 { } fn create_call_endpoint(audio: bool, - statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), + statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte2D), ) -> Result<*mut CallEndpoint> { @@ -419,7 +436,7 @@ fn create_call_endpoint(audio: bool, } #[no_mangle] -pub unsafe extern "C" fn createCallEndpoint(statusCallback: extern "C" fn(CallId, u64, CallDirection, CallMediaType), +pub unsafe extern "C" fn createCallEndpoint(statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte2D)) -> i64 { let answer: i64 = match create_call_endpoint(false, statusCallback, answerCallback, iceUpdateCallback) { From ac4bf2fe51d58a461449400080586841737a68e5 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Wed, 28 Sep 2022 20:11:20 +0200 Subject: [PATCH 11/74] build 0.0.2 version of tring. This now allows incoming calls to be answered on Linux --- src/java/tring/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 5067076c..f85de19c 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.2-SNAPSHOT + 0.0.2 jar UTF-8 From 3426cc5b2420ee8713649a572789cd9904dee704 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 30 Sep 2022 14:47:32 +0200 Subject: [PATCH 12/74] Supply classifier to jar build process --- bin/build-java | 2 +- src/java/tring/pom.xml | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/bin/build-java b/bin/build-java index 5ea5ccd0..5909936e 100755 --- a/bin/build-java +++ b/bin/build-java @@ -146,5 +146,5 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" fi ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h cd ../java/tring - mvn clean install + mvn -Dclassifier=$DEFAULT_PLATFORM clean install ) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index f85de19c..9894b511 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.2 + 0.0.3-SNAPSHOT jar UTF-8 @@ -31,6 +31,22 @@ false + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + classifier-build + + jar + + + ${classifier} + + + + From 25ff9c38568e179d7e5dde4c4f80f1d4afba6399 Mon Sep 17 00:00:00 2001 From: "jose.pereda" Date: Sat, 1 Oct 2022 14:16:57 +0200 Subject: [PATCH 13/74] Allow building for M1 --- .gitignore | 2 ++ bin/build-java | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 271f8a73..a2bd4a56 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ src/jar.list .project .classpath org.eclipse.buildship.core.prefs +src/java/build +src/java/tring/target diff --git a/bin/build-java b/bin/build-java index 5909936e..182ef3fb 100755 --- a/bin/build-java +++ b/bin/build-java @@ -10,10 +10,15 @@ set -e # shellcheck source=bin/env.sh . "$(dirname "$0")"/env.sh -JEXTRACT=/opt/jextract-19 -JDK=/opt/jdk-19 +JEXTRACT=${JEXTRACT:-/opt/jextract-19} +JDK=${JDK:-/opt/jdk-19} TARGET_ARCH=${TARGET_ARCH:-x64} +# darwin only +DEFAULT_MACOS_SDK_VERSION="12.3" +MACOS_SDK_VERSION=${MACOS_SDK_VERSION:-$DEFAULT_MACOS_SDK_VERSION} +MACOS_SDK_PATH="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${MACOS_SDK_VERSION}.sdk" + usage() { echo 'usage: build-java [-d|-r|-c] @@ -100,7 +105,7 @@ case "$(rustup show active-toolchain)" in exit 1 esac -echo "Building for platform ${DEFAULT_PLATFORM}, TARGET_ARCH=${TARGET_ARCH}, GN_ARCH=${GN_ARCH}, CARGO_TARGET=${CARGO_TARGET}" +echo "Building for platform ${DEFAULT_PLATFORM}, TARGET_ARCH=${TARGET_ARCH}, GN_ARCH=${GN_ARCH}, CARGO_TARGET=${CARGO_TARGET}", OUTPUT_DIR=${OUTPUT_DIR} export MACOSX_DEPLOYMENT_TARGET="10.10" @@ -127,24 +132,26 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" then RUSTFLAGS="${RUSTFLAGS_WIN}" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --features java else - OUTPUT_DIR="${OUTPUT_DIR}" cargo build --lib --features java --release + OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --lib --features java --release fi if [ $DEFAULT_PLATFORM = "darwin" ] then mkdir -p ../java/build/darwin cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/build/darwin/libringrtc-"${TARGET_ARCH}".java + ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/darwin -I${MACOS_SDK_PATH}/usr/include --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h elif [ $DEFAULT_PLATFORM = "win32" ] then mkdir -p ../java/build/win32 cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/ringrtc.dll ../java/build/win32/libringrtc-"${TARGET_ARCH}".java + ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/win32 --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h elif [ $DEFAULT_PLATFORM = "linux" ] then mkdir -p ../java/build/linux cp -f target/${BUILD_TYPE}/libringrtc.so ../java/tring/src/main/resources/libringrtc.so cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/build/linux/libringrtc-"${TARGET_ARCH}".java + ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h fi - ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h cd ../java/tring mvn -Dclassifier=$DEFAULT_PLATFORM clean install ) From 650d122e6834eb4f16cb8e6b6230677db7d36d06 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sat, 1 Oct 2022 14:57:21 +0200 Subject: [PATCH 14/74] Add target as a subdir to linux build directory don't add `.java` suffix to darwin lib --- bin/build-java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/build-java b/bin/build-java index 182ef3fb..cd28a2df 100755 --- a/bin/build-java +++ b/bin/build-java @@ -138,7 +138,7 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" if [ $DEFAULT_PLATFORM = "darwin" ] then mkdir -p ../java/build/darwin - cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/build/darwin/libringrtc-"${TARGET_ARCH}".java + cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/build/darwin/libringrtc-"${TARGET_ARCH}" ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/darwin -I${MACOS_SDK_PATH}/usr/include --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h elif [ $DEFAULT_PLATFORM = "win32" ] then @@ -148,8 +148,8 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" elif [ $DEFAULT_PLATFORM = "linux" ] then mkdir -p ../java/build/linux - cp -f target/${BUILD_TYPE}/libringrtc.so ../java/tring/src/main/resources/libringrtc.so - cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/build/linux/libringrtc-"${TARGET_ARCH}".java + cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/tring/src/main/resources/libringrtc.so + #cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/build/linux/libringrtc-"${TARGET_ARCH}".java ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h fi cd ../java/tring From 7db8cb792786e8fd280e92563e5b24154c95101d Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sat, 1 Oct 2022 15:02:32 +0200 Subject: [PATCH 15/74] create resources dir if it doesn't exist --- bin/build-java | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/build-java b/bin/build-java index cd28a2df..117e1836 100755 --- a/bin/build-java +++ b/bin/build-java @@ -135,6 +135,7 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" OUTPUT_DIR="${OUTPUT_DIR}" cargo build --target ${CARGO_TARGET} --lib --features java --release fi + mkdir -p ../java/tring/src/main/resources if [ $DEFAULT_PLATFORM = "darwin" ] then mkdir -p ../java/build/darwin From 717e53ea1ec7cec665613b549db35dcab4e168b1 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sat, 1 Oct 2022 15:09:28 +0200 Subject: [PATCH 16/74] correct cp --- bin/build-java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bin/build-java b/bin/build-java index 117e1836..afada1ba 100755 --- a/bin/build-java +++ b/bin/build-java @@ -139,7 +139,8 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" if [ $DEFAULT_PLATFORM = "darwin" ] then mkdir -p ../java/build/darwin - cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/build/darwin/libringrtc-"${TARGET_ARCH}" + cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/tring/src/main/resources/libringrtc.dylib + # cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/build/darwin/libringrtc-"${TARGET_ARCH}" ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/darwin -I${MACOS_SDK_PATH}/usr/include --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h elif [ $DEFAULT_PLATFORM = "win32" ] then From 7a80287098bf0179ef3fad4a2c4a83b61daacea7 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sat, 1 Oct 2022 17:33:04 +0200 Subject: [PATCH 17/74] required to build a module and export packages --- src/java/tring/src/main/java/module-info.java | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/java/tring/src/main/java/module-info.java diff --git a/src/java/tring/src/main/java/module-info.java b/src/java/tring/src/main/java/module-info.java new file mode 100644 index 00000000..7c0a0add --- /dev/null +++ b/src/java/tring/src/main/java/module-info.java @@ -0,0 +1,5 @@ +module io.privacyresearch.tring { + requires java.logging; + + exports io.privacyresearch.tring; +} From e66409fceb2d3de1a7800cd37c197096de715a64 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sat, 1 Oct 2022 20:16:41 +0200 Subject: [PATCH 18/74] allow clean build for Java Use System.mapLibrary to find the appropriate libraryname --- Makefile | 1 + bin/build-java | 1 + .../main/java/io/privacyresearch/tring/NativeLibLoader.java | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 53955456..d489afa9 100644 --- a/Makefile +++ b/Makefile @@ -128,6 +128,7 @@ clean: $(Q) ./bin/build-gctc --clean $(Q) ./bin/build-electron --clean $(Q) ./bin/build-ios --clean + $(Q) ./bin/build-java --clean $(Q) rm -rf ./src/webrtc/src/out PHONY += distclean diff --git a/bin/build-java b/bin/build-java index afada1ba..19ef2fb5 100755 --- a/bin/build-java +++ b/bin/build-java @@ -35,6 +35,7 @@ clean() rm -rf ./src/rust/target/release rm -rf ./src/webrtc/src/out/debug rm -rf ./src/webrtc/src/out/release + mvn -f ./src/java/tring clean } BUILD_TYPE=release diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java index bde28eab..1acecadc 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java @@ -9,7 +9,8 @@ public class NativeLibLoader { public static void loadLibrary() throws IOException { - InputStream is = NativeLibLoader.class.getResourceAsStream("/libringrtc.so"); + String libName = System.mapLibraryName("ringrtc"); + InputStream is = NativeLibLoader.class.getResourceAsStream(libName); Path target = Files.createTempFile("", ""); Files.copy(is, target, StandardCopyOption.REPLACE_EXISTING); System.load(target.toString()); From 3795836cc4e8883be23aa957aff7ee1156f9da94 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sat, 1 Oct 2022 20:29:43 +0200 Subject: [PATCH 19/74] Use library at the root of the resource folder build 0.0.3 --- src/java/tring/pom.xml | 2 +- .../main/java/io/privacyresearch/tring/NativeLibLoader.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 9894b511..bec0e00e 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.3-SNAPSHOT + 0.0.3 jar UTF-8 diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java index 1acecadc..4a7a92bd 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java @@ -9,7 +9,8 @@ public class NativeLibLoader { public static void loadLibrary() throws IOException { - String libName = System.mapLibraryName("ringrtc"); + String libName = "/"+System.mapLibraryName("ringrtc"); + System.err.println("Will try to load "+libName); InputStream is = NativeLibLoader.class.getResourceAsStream(libName); Path target = Files.createTempFile("", ""); Files.copy(is, target, StandardCopyOption.REPLACE_EXISTING); From fecac0b28c382dea4b140002e5dd5e331984719f Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 2 Oct 2022 16:54:34 +0200 Subject: [PATCH 20/74] Split tring and tringApi --- .gitignore | 1 + src/java/tring/pom.xml | 9 ++- .../tring/NativeLibLoader.java | 3 +- .../io/privacyresearch/tring/OldTringApi.java | 18 ++++++ .../privacyresearch/tring/OldTringBridge.java | 43 ++++++++++++++ ...TringBridge.java => TringServiceImpl.java} | 42 ++++++++++---- src/java/tring/src/main/java/module-info.java | 2 + src/java/tringapi/pom.xml | 52 +++++++++++++++++ .../privacyresearch/tringapi}/TringApi.java | 5 +- .../privacyresearch/tringapi/TringBridge.java | 58 +++++++++++++++++++ .../tringapi/TringService.java | 30 ++++++++++ .../tringapi/src/main/java/module-info.java | 6 ++ 12 files changed, 253 insertions(+), 16 deletions(-) create mode 100644 src/java/tring/src/main/java/io/privacyresearch/tring/OldTringApi.java create mode 100644 src/java/tring/src/main/java/io/privacyresearch/tring/OldTringBridge.java rename src/java/tring/src/main/java/io/privacyresearch/tring/{TringBridge.java => TringServiceImpl.java} (92%) create mode 100644 src/java/tringapi/pom.xml rename src/java/{tring/src/main/java/io/privacyresearch/tring => tringapi/src/main/java/io/privacyresearch/tringapi}/TringApi.java (84%) create mode 100644 src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java create mode 100644 src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java create mode 100644 src/java/tringapi/src/main/java/module-info.java diff --git a/.gitignore b/.gitignore index a2bd4a56..7b98724a 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ src/jar.list org.eclipse.buildship.core.prefs src/java/build src/java/tring/target +/src/java/tringapi/target/ diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index bec0e00e..bcad4538 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,13 +3,20 @@ 4.0.0 io.privacyresearch tring - 0.0.3 + 0.0.4-SNAPSHOT jar UTF-8 19 19 + + + io.privacyresearch + tringapi + 0.0.1-SNAPSHOT + + diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java index 4a7a92bd..9c81b3e1 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/NativeLibLoader.java @@ -8,12 +8,13 @@ public class NativeLibLoader { - public static void loadLibrary() throws IOException { + public static String loadLibrary() throws IOException { String libName = "/"+System.mapLibraryName("ringrtc"); System.err.println("Will try to load "+libName); InputStream is = NativeLibLoader.class.getResourceAsStream(libName); Path target = Files.createTempFile("", ""); Files.copy(is, target, StandardCopyOption.REPLACE_EXISTING); System.load(target.toString()); + return libName; } } diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringApi.java b/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringApi.java new file mode 100644 index 00000000..2d8cc37b --- /dev/null +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringApi.java @@ -0,0 +1,18 @@ +package io.privacyresearch.tring; + +import java.util.List; + +/** + * + * @author johan + */ +@Deprecated +public interface OldTringApi { + + void statusCallback(long callId, long peerId, int dir, int type); + + void answerCallback(byte[] opaque); + + void iceUpdateCallback(List iceCandidates); + +} diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringBridge.java new file mode 100644 index 00000000..3e0acac9 --- /dev/null +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringBridge.java @@ -0,0 +1,43 @@ +package io.privacyresearch.tring; + +import io.privacyresearch.tringapi.TringApi; +import io.privacyresearch.tringapi.TringService; + +import java.util.List; +import java.util.Optional; +import java.util.ServiceLoader; + +/** + * + * @author johan + */ +@Deprecated +public class OldTringBridge { + + private TringService service; + + public OldTringBridge(TringApi api) { + ServiceLoader loader = ServiceLoader.load(TringService.class); + Optional serviceOpt = loader.findFirst(); + this.service = serviceOpt.get(); + this.service.setApi(api); + } + + public void acceptCall() { + service.acceptCall(); + } + + public void proceed(long callId) { + service.proceed(callId); + } + + public void receivedIce(long callId, int senderDeviceId, List ice) { + receivedIce(callId, senderDeviceId, ice); + } + + public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, + byte[] senderKey, byte[] receiverKey, byte[] opaque) { + receivedOffer(peerId, callId, senderDeviceId, receiverDeviceId, senderKey, receiverKey, opaque); + } + +} diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java similarity index 92% rename from src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java rename to src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index d8c763d7..221c5a3e 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringBridge.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -1,42 +1,57 @@ package io.privacyresearch.tring; +import io.privacyresearch.tringapi.TringApi; +import io.privacyresearch.tringapi.TringService; import java.lang.foreign.Addressable; import java.lang.foreign.MemoryAddress; -import java.lang.foreign.MemoryLayout; import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; -import static java.lang.foreign.ValueLayout.ADDRESS; -import java.lang.invoke.VarHandle; import java.util.ArrayList; import java.util.List; -public class TringBridge { +public class TringServiceImpl implements TringService { + private static final TringService instance = new TringServiceImpl(); private static boolean nativeSupport = false; private static long nativeVersion = 0; private MemorySession scope; private long callEndpoint; - private final TringApi api; + private io.privacyresearch.tringapi.TringApi api; private long activeCallId; + static String libName = "unknown"; static { try { - NativeLibLoader.loadLibrary(); + libName = NativeLibLoader.loadLibrary(); nativeSupport = true; nativeVersion = tringlib_h.getVersion(); + } catch (Throwable ex) { System.err.println("No native RingRTC support: "); ex.printStackTrace(); } } + public static TringService provider() { + return instance; + } + + public String getVersionInfo() { + return "TringServiceImpl using "+libName; + } + public static long getNativeVersion() { return nativeVersion; } + + protected TringServiceImpl() { + + } - public TringBridge(TringApi api) { + @Override + public void setApi(io.privacyresearch.tringapi.TringApi api) { this.api = api; initiate(); } @@ -48,6 +63,7 @@ private void initiate() { createAnswerCallback(), createIceUpdateCallback()); } + @Override public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, byte[] senderKey, byte[] receiverKey, byte[] opaque) { int mediaType = 0; @@ -62,16 +78,19 @@ receiverDeviceId, toJByteArray(scope, senderKey), toJByteArray(scope, receiverKe public void setSelfUuid(String uuid) { tringlib_h.setSelfUuid(callEndpoint, toJString(scope, uuid)); } - + + @Override public void proceed(long callId) { tringlib_h.proceedCall(callEndpoint, callId, 0, 0); } - + + @Override public void receivedIce(long callId, int senderDeviceId, List ice) { MemorySegment icePack = toJByteArray2D(scope, ice); tringlib_h.receivedIce(callEndpoint, callId, senderDeviceId, icePack); } - + + @Override public void acceptCall() { tringlib_h.acceptCall(callEndpoint, activeCallId); } @@ -164,7 +183,8 @@ Addressable createStatusCallback() { MemorySegment seg = createCallEndpoint$statusCallback.allocate(sci, scope); return seg.address(); } - + + class StatusCallbackImpl implements createCallEndpoint$statusCallback { @Override public void apply(MemorySegment callId, long _x1, int direction, int type) { diff --git a/src/java/tring/src/main/java/module-info.java b/src/java/tring/src/main/java/module-info.java index 7c0a0add..d8cb3692 100644 --- a/src/java/tring/src/main/java/module-info.java +++ b/src/java/tring/src/main/java/module-info.java @@ -1,5 +1,7 @@ module io.privacyresearch.tring { requires java.logging; + requires io.privacyresearch.tringapi; exports io.privacyresearch.tring; + provides io.privacyresearch.tringapi.TringService with io.privacyresearch.tring.TringServiceImpl; } diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml new file mode 100644 index 00000000..f16f24d3 --- /dev/null +++ b/src/java/tringapi/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + io.privacyresearch + tringapi + 0.0.1-SNAPSHOT + jar + + UTF-8 + 19 + 19 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + --enable-preview + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + false + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + + + + gluon-nexus + https://nexus.gluonhq.com/nexus/content/repositories/releases + + + gluon-nexus + https://nexus.gluonhq.com/nexus/content/repositories/public-snapshots + + + + diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java similarity index 84% rename from src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java rename to src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java index 42d09405..f3834578 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringApi.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java @@ -1,4 +1,4 @@ -package io.privacyresearch.tring; +package io.privacyresearch.tringapi; import java.util.List; @@ -7,11 +7,10 @@ * @author johan */ public interface TringApi { - + void statusCallback(long callId, long peerId, int dir, int type); void answerCallback(byte[] opaque); void iceUpdateCallback(List iceCandidates); - } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java new file mode 100644 index 00000000..5cbd4f1b --- /dev/null +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -0,0 +1,58 @@ +package io.privacyresearch.tringapi; + +import java.util.List; +import java.util.Optional; +import java.util.ServiceLoader; +import java.util.logging.Logger; + + /** + * This class provides the access points for the application to interact with + * RingRTC. + * Methods here are invoked by Equation. + * When RingRTC wants to call back into the application, the TringApi interface + * is used. + * @author johan + */ +public class TringBridge { + + private TringService service; + private static final Logger LOG = Logger.getLogger(TringBridge.class.getName()); + + public TringBridge(final TringApi api) { + ServiceLoader loader = ServiceLoader.load(TringService.class); + Optional serviceOpt = loader.findFirst(); + serviceOpt.ifPresentOrElse(s -> { + this.service = s; + this.service.setApi(api); + }, () -> { + LOG.warning("No tring service!"); + }); + + } + + public String getVersionInfo() { + if (service == null) { + return "No TringService registered"; + } else { + return service.getVersionInfo(); + } + } + + public void acceptCall() { + service.acceptCall(); + } + + public void proceed(long callId) { + service.proceed(callId); + } + + public void receivedIce(long callId, int senderDeviceId, List ice) { + service.receivedIce(callId, senderDeviceId, ice); + } + + public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, + byte[] senderKey, byte[] receiverKey, byte[] opaque) { + service.receivedOffer(peerId, callId, senderDeviceId, receiverDeviceId, senderKey, receiverKey, opaque); + } + +} diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java new file mode 100644 index 00000000..2c40158b --- /dev/null +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -0,0 +1,30 @@ + package io.privacyresearch.tringapi; + +import java.util.List; + + /** + * Implementations of this interface provides the access points for the application to interact with + * RingRTC. + * Methods here are invoked by TringBridge, which is invoked by Equation. + * When RingRTC wants to call back into the application, the TringApi interface + * is used. + * @author johan + */ +public interface TringService { + + public void setApi(TringApi api); + + public void acceptCall(); + + public void proceed(long callId); + + public void receivedIce(long callId, int senderDeviceId, List ice); + + public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, + byte[] senderKey, byte[] receiverKey, byte[] opaque); + + public default String getVersionInfo() { + return "Unresolved TringService"; + } + +} diff --git a/src/java/tringapi/src/main/java/module-info.java b/src/java/tringapi/src/main/java/module-info.java new file mode 100644 index 00000000..6d11de95 --- /dev/null +++ b/src/java/tringapi/src/main/java/module-info.java @@ -0,0 +1,6 @@ +module io.privacyresearch.tringapi { + requires java.logging; + + exports io.privacyresearch.tringapi; + uses io.privacyresearch.tringapi.TringService; +} From d963ba86048a6f47d4291f95e1b8c5060d79ac46 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 2 Oct 2022 20:21:13 +0200 Subject: [PATCH 21/74] Allow to enable audio recording --- bin/build-java | 4 +++- .../tring/TringServiceImpl.java | 9 ++++++++ src/rust/src/java/java.rs | 21 +++++++++++++++++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/bin/build-java b/bin/build-java index 19ef2fb5..9cc1cec3 100755 --- a/bin/build-java +++ b/bin/build-java @@ -137,12 +137,14 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" fi mkdir -p ../java/tring/src/main/resources + ARCH_CLASSIFIER="" if [ $DEFAULT_PLATFORM = "darwin" ] then mkdir -p ../java/build/darwin cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/tring/src/main/resources/libringrtc.dylib # cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/build/darwin/libringrtc-"${TARGET_ARCH}" ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/darwin -I${MACOS_SDK_PATH}/usr/include --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h + ARCH_CLASSIFIER="x86_64" elif [ $DEFAULT_PLATFORM = "win32" ] then mkdir -p ../java/build/win32 @@ -156,5 +158,5 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h fi cd ../java/tring - mvn -Dclassifier=$DEFAULT_PLATFORM clean install + mvn -Dclassifier=$DEFAULT_PLATFORM-$ARCH_CLASSIFIER clean install ) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 221c5a3e..53338c8b 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -9,6 +9,7 @@ import java.lang.foreign.ValueLayout; import java.util.ArrayList; import java.util.List; +import java.util.logging.Logger; public class TringServiceImpl implements TringService { @@ -22,6 +23,8 @@ public class TringServiceImpl implements TringService { private long activeCallId; static String libName = "unknown"; + private static final Logger LOG = Logger.getLogger(TringServiceImpl.class.getName()); + static { try { libName = NativeLibLoader.loadLibrary(); @@ -69,6 +72,7 @@ public void receivedOffer(String peerId, long callId, int senderDeviceId, int re int mediaType = 0; long ageSec = 0; this.activeCallId = callId; + LOG.info("Pass received offer to tringlib"); tringlib_h.receivedOffer(callEndpoint, toJString(scope, peerId), callId, mediaType, senderDeviceId, receiverDeviceId, toJByteArray(scope, senderKey), toJByteArray(scope, receiverKey), toJByteArray(scope, opaque), @@ -92,6 +96,11 @@ public void receivedIce(long callId, int senderDeviceId, List ice) { @Override public void acceptCall() { + LOG.info("Set audioInput to 0"); + tringlib_h.setAudioInput(callEndpoint, (short)0); + LOG.info("Set audiorecording"); + tringlib_h.setOutgoingAudioEnabled(callEndpoint, true); + LOG.info("And now accept the call"); tringlib_h.acceptCall(callEndpoint, activeCallId); } diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 9c0e8786..eb220ec9 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -315,7 +315,7 @@ pub struct CallEndpoint { outgoing_video_track: VideoTrack, // Boxed so we can pass it as a Box incoming_video_sink: Box, - + peer_connection_factory: PeerConnectionFactory, } impl CallEndpoint { @@ -372,6 +372,7 @@ impl CallEndpoint { outgoing_video_source, outgoing_video_track, incoming_video_sink, + peer_connection_factory, }) } } @@ -541,10 +542,10 @@ pub unsafe extern "C" fn receivedIce(endpoint: i64, call_id: u64, sender_device_ ); } - #[no_mangle] pub unsafe extern "C" fn acceptCall(endpoint: i64, call_id: u64) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("now accept call"); let call_id = CallId::from(call_id); endpoint.call_manager.accept_call(call_id); 573 @@ -558,4 +559,20 @@ pub unsafe extern "C" fn signalMessageSent(endpoint: i64, call_id: CallId) -> i6 135 } +#[no_mangle] +pub unsafe extern "C" fn setAudioInput(endpoint: i64, index: u16) -> i64 { + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("Have to set audio_recordig_device to {}", index); + endpoint.peer_connection_factory.set_audio_recording_device(index); + 1 +} + +#[no_mangle] +pub unsafe extern "C" fn setOutgoingAudioEnabled(endpoint: i64, enable: bool) -> i64 { + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("Have to set outgoing audio enabled to {}", enable); + endpoint.outgoing_audio_track.set_enabled(enable); + 1 +} + From 491fb9a77d4c75e5b7e9a54f65df59064e64cce0 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 2 Oct 2022 20:49:04 +0200 Subject: [PATCH 22/74] Use CARGO ARCH as the architecture for the classifier --- bin/build-java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bin/build-java b/bin/build-java index 9cc1cec3..4f70141c 100755 --- a/bin/build-java +++ b/bin/build-java @@ -137,7 +137,6 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" fi mkdir -p ../java/tring/src/main/resources - ARCH_CLASSIFIER="" if [ $DEFAULT_PLATFORM = "darwin" ] then mkdir -p ../java/build/darwin @@ -158,5 +157,5 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h fi cd ../java/tring - mvn -Dclassifier=$DEFAULT_PLATFORM-$ARCH_CLASSIFIER clean install + mvn -Dclassifier=$DEFAULT_PLATFORM-$CARGO_ARCH clean install ) From 51e5798145cabdb911f71508a3a6446e3025395f Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 2 Oct 2022 20:57:47 +0200 Subject: [PATCH 23/74] Add very basic info on the Java port --- src/java/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/java/README.md diff --git a/src/java/README.md b/src/java/README.md new file mode 100644 index 00000000..18ee0c7e --- /dev/null +++ b/src/java/README.md @@ -0,0 +1,14 @@ +The Java implementation consists of 2 Java projects, and a Rust component. + +tringapi: this contains the API that can be accessed by the application, +without any dependencies (no application model classes or ringrtc structs). +It uses the Java ServiceLoader concept to find implementations of the +TringService. + +tring: this contains platform-specific implementations of the TringService. +The source code is mainly auto-generated by jextract. The implementation +itself is in TringServiceImpl, and it is made available via module-info.java + +Rust component: +java.rs contains the implementation of methods invoked by TringServiceImpl. +It is similar to electron.js From 2e0124dfc946314a50dcd49379818a139536a4a9 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 2 Oct 2022 21:11:06 +0200 Subject: [PATCH 24/74] allow to build releases (tring 0.0.4 and tringapi 0.0.1) --- src/java/tring/pom.xml | 2 +- src/java/tringapi/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index bcad4538..36e9f173 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.4-SNAPSHOT + 0.0.4 jar UTF-8 diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index f16f24d3..c8a9cefe 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.1-SNAPSHOT + 0.0.1 jar UTF-8 From 9da574b6e549625c288e267c871223069112f377 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 2 Oct 2022 21:25:29 +0200 Subject: [PATCH 25/74] use 0.0.1 instead of a snapshot --- src/java/tring/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 36e9f173..9bf16b88 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.1-SNAPSHOT + 0.0.1 From e052df735ff5e547260cc17b70fcfb18a6be40a0 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 2 Oct 2022 21:40:33 +0200 Subject: [PATCH 26/74] bump release versions of tring and tringapi --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 9bf16b88..03ad85f9 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.4 + 0.0.5-SNAPSHOT jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.1 + 0.0.2-SNAPSHOT diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index c8a9cefe..acfd9c38 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.1 + 0.0.2-SNAPSHOT jar UTF-8 From 7c8a10f451142dc2bf5fcc1670cafd28ce0e5777 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 3 Oct 2022 08:39:14 +0200 Subject: [PATCH 27/74] add call ifgnore/hangup flow --- bin/build-java | 4 +++- .../privacyresearch/tring/TringServiceImpl.java | 12 ++++++++++++ .../privacyresearch/tringapi/TringBridge.java | 8 ++++++++ .../privacyresearch/tringapi/TringService.java | 2 ++ src/rust/src/java/java.rs | 17 +++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/bin/build-java b/bin/build-java index 4f70141c..62cf589e 100755 --- a/bin/build-java +++ b/bin/build-java @@ -156,6 +156,8 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" #cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.so ../java/build/linux/libringrtc-"${TARGET_ARCH}".java ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/linux --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h fi - cd ../java/tring + cd ../java/tringapi + mvn clean install + cd ../tring mvn -Dclassifier=$DEFAULT_PLATFORM-$CARGO_ARCH clean install ) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 53338c8b..e43bfc7a 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -104,6 +104,18 @@ public void acceptCall() { tringlib_h.acceptCall(callEndpoint, activeCallId); } + @Override + public void ignoreCall() { + LOG.info("Ignore the call"); + tringlib_h.ignoreCall(callEndpoint, activeCallId); + } + + @Override + public void hangupCall() { + LOG.info("Hangup the call"); + tringlib_h.hangupCall(callEndpoint); + } + static MemorySegment toJByteArray2D(MemorySession ms, List rows) { MemorySegment answer = JByteArray2D.allocate(ms); JByteArray2D.len$set(answer, rows.size()); diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index 5cbd4f1b..46019787 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -42,6 +42,14 @@ public void acceptCall() { service.acceptCall(); } + public void ignoreCall() { + service.ignoreCall(); + } + + public void hangupCall() { + service.hangupCall(); + } + public void proceed(long callId) { service.proceed(callId); } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index 2c40158b..ceb90993 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -15,6 +15,8 @@ public interface TringService { public void setApi(TringApi api); public void acceptCall(); + public void ignoreCall(); + public void hangupCall(); public void proceed(long callId); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index eb220ec9..ec91aa39 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -551,6 +551,23 @@ pub unsafe extern "C" fn acceptCall(endpoint: i64, call_id: u64) -> i64 { 573 } +#[no_mangle] +pub unsafe extern "C" fn ignoreCall(endpoint: i64, call_id: u64) -> i64 { + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("now drop (ignore) call"); + let call_id = CallId::from(call_id); + endpoint.call_manager.drop_call(call_id); + 1 +} + +#[no_mangle] +pub unsafe extern "C" fn hangupCall(endpoint: i64) -> i64 { + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("now hangup call"); + endpoint.call_manager.hangup(); + 1 +} + #[no_mangle] pub unsafe extern "C" fn signalMessageSent(endpoint: i64, call_id: CallId) -> i64 { let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); From 577409a13bc7c95a34aa787b09328497e5a474d6 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Tue, 4 Oct 2022 21:19:46 +0200 Subject: [PATCH 28/74] first steps for outgoingcall --- .../tring/TringServiceImpl.java | 62 ++++++++++---- .../io/privacyresearch/tringapi/TringApi.java | 3 + .../privacyresearch/tringapi/TringBridge.java | 11 ++- .../tringapi/TringService.java | 4 + src/rust/build.rs | 2 +- src/rust/src/java/java.rs | 85 ++++++++++++++++--- 6 files changed, 137 insertions(+), 30 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index e43bfc7a..d31e7b93 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -9,6 +9,7 @@ import java.lang.foreign.ValueLayout; import java.util.ArrayList; import java.util.List; +import java.util.Random; import java.util.logging.Logger; public class TringServiceImpl implements TringService { @@ -63,7 +64,7 @@ private void initiate() { scope = MemorySession.openShared(); tringlib_h.initRingRTC(toJString(scope, "Hello from Java")); this.callEndpoint = tringlib_h.createCallEndpoint(createStatusCallback(), - createAnswerCallback(), createIceUpdateCallback()); + createAnswerCallback(), createOfferCallback(), createIceUpdateCallback()); } @Override @@ -79,6 +80,18 @@ receiverDeviceId, toJByteArray(scope, senderKey), toJByteArray(scope, receiverKe ageSec); } + @Override + public void receivedAnswer(String peerId, long callId, int senderDeviceId, + byte[] senderKey, byte[] receiverKey, byte[] opaque) { + int mediaType = 0; + long ageSec = 0; + this.activeCallId = callId; + LOG.info("Pass received offer to tringlib"); + tringlib_h.receivedAnswer(callEndpoint, toJString(scope, peerId), callId, senderDeviceId, + toJByteArray(scope, senderKey), toJByteArray(scope, receiverKey), + toJByteArray(scope, opaque) + ); + } public void setSelfUuid(String uuid) { tringlib_h.setSelfUuid(callEndpoint, toJString(scope, uuid)); } @@ -115,6 +128,19 @@ public void hangupCall() { LOG.info("Hangup the call"); tringlib_h.hangupCall(callEndpoint); } + + /** + * start a call and return the call_id + * @return a generated call_id + */ + @Override + public long startOutgoingCall(long callId, String peerId, int localDeviceId) { + LOG.info("Tring will start outgoing call to "+peerId+" with localDevice "+localDeviceId); + tringlib_h.setAudioInput(callEndpoint, (short)0); + tringlib_h.setAudioOutput(callEndpoint, (short)0); + tringlib_h.createOutgoingCall(callEndpoint, toJString(scope, peerId), false, localDeviceId, callId); + return callId; + } static MemorySegment toJByteArray2D(MemorySession ms, List rows) { MemorySegment answer = JByteArray2D.allocate(ms); @@ -233,6 +259,23 @@ public void apply(MemorySegment opaque) { } } + Addressable createOfferCallback() { + OfferCallbackImpl sci = new OfferCallbackImpl(); + MemorySegment seg = createCallEndpoint$offerCallback.allocate(sci, scope); + return seg.address(); + } + + class OfferCallbackImpl implements createCallEndpoint$offerCallback { + @Override + public void apply(MemorySegment opaque) { + byte[] bytes = fromJArrayByte(scope, opaque); + api.offerCallback(bytes); + System.err.println("TRING, offer sent"); + sendAck(); + System.err.println("TRING, ack sent"); + } + } + Addressable createIceUpdateCallback() { IceUpdateCallbackImpl sci = new IceUpdateCallbackImpl(); MemorySegment seg = createCallEndpoint$iceUpdateCallback.allocate(sci, scope); @@ -243,8 +286,8 @@ class IceUpdateCallbackImpl implements createCallEndpoint$iceUpdateCallback { @Override public void apply(MemorySegment icePack) { long length = JArrayByte2D.len$get(icePack); - System.err.println("IcePack has "+length+ " ice updates, address at "+icePack); - List iceCandidates = new ArrayList<>(); + System.err.println("IcePack has "+length+ " ice updates, address at "+icePack); + List iceCandidates = new ArrayList<>(); MemorySegment allData = JArrayByte2D.data$slice(icePack); long allSize = allData.byteSize(); System.err.println("All size = " + allSize); @@ -259,18 +302,7 @@ public void apply(MemorySegment icePack) { System.err.println("ICbytes = " + java.util.Arrays.toString(rowBytes)); iceCandidates.add(rowBytes); } - -// MemorySegment rows = JArrayByte2D.data$slice(icePack); -// // MemorySegment rows = JArrayByte2D.buff$slice(icePack); -// for (int i = 0; i < length; i++) { -// MemorySegment row = rows.asSlice(16*i, 16); -// long bl = JArrayByte.len$get(row); -// MemorySegment byteSegment = JArrayByte.data$slice(row); -// byte[] rowByte = fromJArrayByte(scope, byteSegment); -// iceCandidates.add(rowByte); -// } - api.iceUpdateCallback(iceCandidates); - // waveCallManager.handleSendIceCandidates(activeCall, false, iceCandidates); + api.iceUpdateCallback(iceCandidates); sendAck(); System.err.println("TRINGBRIDGE, iceUpdate done!"); diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java index f3834578..71175b6a 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java @@ -12,5 +12,8 @@ public interface TringApi { void answerCallback(byte[] opaque); + void offerCallback(byte[] opaque); + void iceUpdateCallback(List iceCandidates); + } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index 46019787..cd8ca217 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -29,7 +29,7 @@ public TringBridge(final TringApi api) { }); } - + public String getVersionInfo() { if (service == null) { return "No TringService registered"; @@ -63,4 +63,13 @@ public void receivedOffer(String peerId, long callId, int senderDeviceId, int re service.receivedOffer(peerId, callId, senderDeviceId, receiverDeviceId, senderKey, receiverKey, opaque); } + public void receivedAnswer(String peerId, long callId, int receiverDeviceId, + byte[] senderKey, byte[] receiverKey, byte[] opaque) { + service.receivedAnswer(peerId, callId, receiverDeviceId, senderKey, receiverKey, opaque); + } + + public long startOutgoingCall(long callId, String peerId, int localDeviceId) { + return service.startOutgoingCall(callId, peerId, localDeviceId); + } + } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index ceb90993..0026e321 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -24,6 +24,10 @@ public interface TringService { public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, byte[] senderKey, byte[] receiverKey, byte[] opaque); + + public void receivedAnswer(String peerId, long callId, int senderDeviceId, + byte[] senderKey, byte[] receiverKey, byte[] opaque); + public long startOutgoingCall(long callId, String peerId, int localDeviceId); public default String getVersionInfo() { return "Unresolved TringService"; diff --git a/src/rust/build.rs b/src/rust/build.rs index a59237d1..cbec362b 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("unable to generate bindings") + .expect("uunable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index ec91aa39..3b3569a4 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -100,6 +100,7 @@ pub enum Event { struct EventReporter { pub statusCallback: unsafe extern "C" fn(CallId, u64, i32, CallMediaType), pub answerCallback: unsafe extern "C" fn(JArrayByte), + pub offerCallback: unsafe extern "C" fn(JArrayByte), pub iceUpdateCallback: unsafe extern "C" fn(JArrayByte2D), sender: Sender, report: Arc, @@ -108,11 +109,13 @@ struct EventReporter { impl EventReporter { fn new(statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), + offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte2D), sender: Sender, report: impl Fn() + Send + Sync + 'static) -> Self { Self { statusCallback, answerCallback, + offerCallback, iceUpdateCallback, sender, report: Arc::new(report), @@ -124,6 +127,13 @@ impl EventReporter { Event::SendSignaling(_peer_id, _maybe_device_id, _call_id, signal) => { info!("[JV] SendSignalingEvent"); match signal { + signaling::Message::Offer(offer) => { + info!("[JV] SendSignaling OFFER Event"); + let op = JArrayByte::new(offer.opaque); + unsafe { + (self.offerCallback)(op); + } + } signaling::Message::Answer(answer) => { info!("[JV] SendSignaling ANSWER Event"); let op = JArrayByte::new(answer.opaque); @@ -150,6 +160,13 @@ impl EventReporter { (self.statusCallback)(call_id, 1,direction, call_media_type); } } + Event::CallState(_peer_id, call_id, CallState::Outgoing(call_media_type)) => { + info!("[JV] CALLSTATEEVEMNT"); + let direction = 1; + unsafe { + (self.statusCallback)(call_id, 1,direction, call_media_type); + } + } Event::CallState(_peer_id, call_id, state) => { info!("[JV] CallState changed"); let (state_string, state_index) = match state { @@ -323,6 +340,7 @@ impl CallEndpoint { use_new_audio_device_module: bool, statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), + offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte2D), ) -> Result { // Relevant for both group calls and 1:1 calls @@ -341,8 +359,7 @@ impl CallEndpoint { let event_reported = Arc::new(AtomicBool::new(false)); - // let event_reporter = EventReporter::new(startCallback, answerCallback, iceUpdateCallback, events_sender, move || { - let event_reporter = EventReporter::new(statusCallback, answerCallback, iceUpdateCallback, events_sender, move || { + let event_reporter = EventReporter::new(statusCallback, answerCallback, offerCallback, iceUpdateCallback, events_sender, move || { info!("[JV] EVENT_REPORTER, NYI"); if event_reported.swap(true, std::sync::atomic::Ordering::Relaxed) { return; @@ -426,21 +443,17 @@ pub unsafe extern "C" fn getVersion() -> i64 { 1 } -fn create_call_endpoint(audio: bool, - statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), - answerCallback: extern "C" fn(JArrayByte), - iceUpdateCallback: extern "C" fn(JArrayByte2D), - ) -> Result<*mut CallEndpoint> { - let call_endpoint = CallEndpoint::new(audio, statusCallback, answerCallback, iceUpdateCallback).unwrap(); - let call_endpoint_box = Box::new(call_endpoint); - Ok(Box::into_raw(call_endpoint_box)) -} #[no_mangle] pub unsafe extern "C" fn createCallEndpoint(statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), + offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte2D)) -> i64 { - let answer: i64 = match create_call_endpoint(false, statusCallback, answerCallback, iceUpdateCallback) { + let call_endpoint = CallEndpoint::new(false, statusCallback, answerCallback, offerCallback, iceUpdateCallback).unwrap(); + let call_endpoint_box = Box::new(call_endpoint); + let boxx: Result<*mut CallEndpoint> = Ok(Box::into_raw(call_endpoint_box)); + + let answer: i64 = match boxx { Ok(v) => v as i64, Err(e) => { info!("Error creating callEndpoint: {}", e); @@ -487,11 +500,49 @@ pub unsafe extern "C" fn receivedOffer(endpoint: i64, peerId: JString, call_id: receiver_identity_key: receiver_key.to_vec_u8(), }, ); + 1 +} - +#[no_mangle] +pub unsafe extern "C" fn receivedAnswer(endpoint: i64, peerId: JString, call_id: u64, + sender_device_id:u32, sender_key: JByteArray, receiver_key: JByteArray, opaque: JByteArray) -> i64 { + let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + let peer_id = JString::from(peerId); + let call_id = CallId::new(call_id); + let answer = signaling::Answer::new(opaque.to_vec_u8()).unwrap(); + callendpoint.call_manager.received_answer( + call_id, + signaling::ReceivedAnswer { + answer, + sender_device_id, + sender_identity_key: sender_key.to_vec_u8(), + receiver_identity_key: receiver_key.to_vec_u8(), + }, + ); 1 } +// suppy a random callid +#[no_mangle] +pub unsafe extern "C" fn createOutgoingCall(endpoint: i64, peer_id: JString, video_enabled: bool, local_device_id:u32, call_id: i64) -> i64 { + info!("create outgoing call"); + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + let peer_id = peer_id.to_string(); + let media_type = if video_enabled { + CallMediaType::Video + } else { + CallMediaType::Audio + }; + let call_id = CallId::from(call_id); + endpoint.call_manager.create_outgoing_call( + peer_id, + call_id, + media_type, + local_device_id, + ); + 1 +} + #[no_mangle] pub unsafe extern "C" fn proceedCall(endpoint: i64, call_id: u64, bandwidth_mode: i32, audio_levels_interval_millis:i32) -> i64 { info!("Proceeding with call"); @@ -584,6 +635,14 @@ pub unsafe extern "C" fn setAudioInput(endpoint: i64, index: u16) -> i64 { 1 } +#[no_mangle] +pub unsafe extern "C" fn setAudioOutput(endpoint: i64, index: u16) -> i64 { + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("Have to set audio_output_device to {}", index); + endpoint.peer_connection_factory.set_audio_playout_device(index); + 1 +} + #[no_mangle] pub unsafe extern "C" fn setOutgoingAudioEnabled(endpoint: i64, enable: bool) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); From 6b24bce0be65d8c0257cab9bea815ed756af8d6b Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Wed, 5 Oct 2022 11:16:58 +0200 Subject: [PATCH 29/74] add more debugging --- .../privacyresearch/tring/TringServiceImpl.java | 8 +++++++- src/rust/src/java/jtypes.rs | 15 ++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index d31e7b93..7d773524 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -294,7 +294,13 @@ public void apply(MemorySegment icePack) { for (int i = 0; i < length; i++) { int rowLength = (int) JByteArray.len$get(allData, i); MemoryAddress rowData = JByteArray.buff$get(allData, i); - System.err.println("Got length for " + i + ": " + rowLength); + long rawRowAddress = rowData.toRawLongValue(); + System.err.println("Got length for " + i + ": " + rowLength+", raw address at "+rawRowAddress); + byte b0 = rowData.get(ValueLayout.JAVA_BYTE, 0); + byte b1 = rowData.get(ValueLayout.JAVA_BYTE, 1); + byte b2 = rowData.get(ValueLayout.JAVA_BYTE, 2); + byte b3 = rowData.get(ValueLayout.JAVA_BYTE, 3); + System.err.println("b0 = " + b0 + ", b1 = " + b1 + ", b2 = " + b2+", b3 = " + b3); byte[] rowBytes = new byte[rowLength]; MemorySegment destSegment = MemorySegment.ofArray(rowBytes); MemorySegment rowSegment = MemorySegment.ofAddress(rowData, rowLength, scope); diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index 5557da16..90288c4f 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -51,26 +51,19 @@ pub struct JArrayByte2D { impl JArrayByte2D { pub fn new(vector: Vec) -> Self { +info!("I have to create a jArrayByte with {} elements" , vector.len()); let vlen = vector.len(); let mut myrows: [JByteArray; 25] = [JByteArray::empty(); 25]; for i in 0..25 { if (i < vlen) { myrows[i] = JByteArray::from_data(vector[i].opaque.as_ptr(), vector[i].opaque.len()); +info!("IceVec[{}] = {:?}", i, vector[i].opaque); } else { myrows[i] = JByteArray::new(Vec::new()); } +info!("Myrow[{}] : {}", i, myrows[i]); } - -/* - let mut myrows: [JArrayByte; 2] = [JArrayByte::empty(); 2]; - for i in 0..2 { - if (i < vlen) { - myrows[i] = JArrayByte::new(vector[i].opaque.clone()); - } else { - myrows[i] = JArrayByte::new(Vec::new()); - } - } -*/ +info!("data at {:?}", myrows); JArrayByte2D { len: vlen, data: myrows, From 4bdc3641ed3a385ac29af3a255dc34c5bee795bf Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Wed, 5 Oct 2022 20:59:06 +0200 Subject: [PATCH 30/74] send ice messages one by one --- .../tring/TringServiceImpl.java | 55 +++++++++++-------- src/rust/src/java/java.rs | 16 ++++-- src/rust/src/java/jtypes.rs | 18 ++++-- 3 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 7d773524..68780f15 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -285,29 +285,38 @@ Addressable createIceUpdateCallback() { class IceUpdateCallbackImpl implements createCallEndpoint$iceUpdateCallback { @Override public void apply(MemorySegment icePack) { - long length = JArrayByte2D.len$get(icePack); - System.err.println("IcePack has "+length+ " ice updates, address at "+icePack); - List iceCandidates = new ArrayList<>(); - MemorySegment allData = JArrayByte2D.data$slice(icePack); - long allSize = allData.byteSize(); - System.err.println("All size = " + allSize); - for (int i = 0; i < length; i++) { - int rowLength = (int) JByteArray.len$get(allData, i); - MemoryAddress rowData = JByteArray.buff$get(allData, i); - long rawRowAddress = rowData.toRawLongValue(); - System.err.println("Got length for " + i + ": " + rowLength+", raw address at "+rawRowAddress); - byte b0 = rowData.get(ValueLayout.JAVA_BYTE, 0); - byte b1 = rowData.get(ValueLayout.JAVA_BYTE, 1); - byte b2 = rowData.get(ValueLayout.JAVA_BYTE, 2); - byte b3 = rowData.get(ValueLayout.JAVA_BYTE, 3); - System.err.println("b0 = " + b0 + ", b1 = " + b1 + ", b2 = " + b2+", b3 = " + b3); - byte[] rowBytes = new byte[rowLength]; - MemorySegment destSegment = MemorySegment.ofArray(rowBytes); - MemorySegment rowSegment = MemorySegment.ofAddress(rowData, rowLength, scope); - destSegment.copyFrom(rowSegment); - System.err.println("ICbytes = " + java.util.Arrays.toString(rowBytes)); - iceCandidates.add(rowBytes); - } + byte[] bytes = fromJArrayByte(scope, icePack); + List iceCandidates = new ArrayList<>(); + iceCandidates.add(bytes); + +// long length = JArrayByte2D.len$get(icePack); +// System.err.println("IcePack has "+length+ " ice updates, address at "+icePack); +// List iceCandidates = new ArrayList<>(); +// MemorySegment allData = JArrayByte2D.data$slice(icePack); +// long allSize = allData.byteSize(); +// System.err.println("All size = " + allSize); +// for (int i = 0; i < length; i++) { +// MemorySegment slice = allData.asSlice(8+264*i, 264); +// byte[] rowBytes = fromJArrayByte(scope, slice); +// +// int rowLenght = (int) JArrayByte.len$get(slice); +// JArrayByte. +// int rowLength = (int) JByteArray.len$get(allData, i); +// MemoryAddress rowData = JByteArray.buff$get(allData, i); +// long rawRowAddress = rowData.toRawLongValue(); +// System.err.println("Got length for " + i + ": " + rowLength+", raw address at "+rawRowAddress); +// byte b0 = rowData.get(ValueLayout.JAVA_BYTE, 0); +// byte b1 = rowData.get(ValueLayout.JAVA_BYTE, 1); +// byte b2 = rowData.get(ValueLayout.JAVA_BYTE, 2); +// byte b3 = rowData.get(ValueLayout.JAVA_BYTE, 3); +// System.err.println("b0 = " + b0 + ", b1 = " + b1 + ", b2 = " + b2+", b3 = " + b3); +// byte[] rowBytes = new byte[rowLength]; +// MemorySegment destSegment = MemorySegment.ofArray(rowBytes); +// MemorySegment rowSegment = MemorySegment.ofAddress(rowData, rowLength, scope); +// destSegment.copyFrom(rowSegment); +// System.err.println("ICbytes = " + java.util.Arrays.toString(rowBytes)); +// iceCandidates.add(rowBytes); +// } api.iceUpdateCallback(iceCandidates); sendAck(); System.err.println("TRINGBRIDGE, iceUpdate done!"); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 3b3569a4..68a9e21e 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -101,7 +101,7 @@ struct EventReporter { pub statusCallback: unsafe extern "C" fn(CallId, u64, i32, CallMediaType), pub answerCallback: unsafe extern "C" fn(JArrayByte), pub offerCallback: unsafe extern "C" fn(JArrayByte), - pub iceUpdateCallback: unsafe extern "C" fn(JArrayByte2D), + pub iceUpdateCallback: unsafe extern "C" fn(JArrayByte), sender: Sender, report: Arc, } @@ -110,7 +110,7 @@ impl EventReporter { fn new(statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), - iceUpdateCallback: extern "C" fn(JArrayByte2D), + iceUpdateCallback: extern "C" fn(JArrayByte), sender: Sender, report: impl Fn() + Send + Sync + 'static) -> Self { Self { statusCallback, @@ -143,9 +143,13 @@ impl EventReporter { } signaling::Message::Ice(ice) => { info!("[JV] SendSignaling ICE Event"); - let icepack: JArrayByte2D = JArrayByte2D::new(ice.candidates); +let ilen = ice.candidates.len(); + // let icepack: JArrayByte2D = JArrayByte2D::new(ice.candidates); unsafe { - (self.iceUpdateCallback)(icepack); +for i in 0..ilen { + // (self.iceUpdateCallback)(icepack); + (self.iceUpdateCallback)(JArrayByte::new(ice.candidates[i].opaque.clone())); +} } } _ => { @@ -341,7 +345,7 @@ impl CallEndpoint { statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), - iceUpdateCallback: extern "C" fn(JArrayByte2D), + iceUpdateCallback: extern "C" fn(JArrayByte), ) -> Result { // Relevant for both group calls and 1:1 calls let (events_sender, _events_receiver) = channel::(); @@ -448,7 +452,7 @@ pub unsafe extern "C" fn getVersion() -> i64 { pub unsafe extern "C" fn createCallEndpoint(statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), - iceUpdateCallback: extern "C" fn(JArrayByte2D)) -> i64 { + iceUpdateCallback: extern "C" fn(JArrayByte)) -> i64 { let call_endpoint = CallEndpoint::new(false, statusCallback, answerCallback, offerCallback, iceUpdateCallback).unwrap(); let call_endpoint_box = Box::new(call_endpoint); let boxx: Result<*mut CallEndpoint> = Ok(Box::into_raw(call_endpoint_box)); diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index 90288c4f..bf5e1fe5 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -24,6 +24,11 @@ pub struct JArrayByte { pub data: [u8; 256], } +impl fmt::Display for JArrayByte { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "JArrayByte with {} bytes at {:?}", self.len, &(self.data)) + } +} impl JArrayByte { pub fn new(vector: Vec ) -> Self { let vlen = vector.len(); @@ -46,27 +51,30 @@ impl JArrayByte { #[derive(Debug)] pub struct JArrayByte2D { pub len: usize, - pub data: [JByteArray;25], + pub data: [u8; 256], + // pub data: [JArrayByte;25], } impl JArrayByte2D { pub fn new(vector: Vec) -> Self { info!("I have to create a jArrayByte with {} elements" , vector.len()); let vlen = vector.len(); - let mut myrows: [JByteArray; 25] = [JByteArray::empty(); 25]; + let mut myrows: [JArrayByte; 25] = [JArrayByte::empty(); 25]; for i in 0..25 { if (i < vlen) { - myrows[i] = JByteArray::from_data(vector[i].opaque.as_ptr(), vector[i].opaque.len()); + myrows[i] = JArrayByte::new(vector[i].opaque.clone()); + // myrows[i] = JByteArray::from_data(vector[i].opaque.as_ptr(), vector[i].opaque.len()); info!("IceVec[{}] = {:?}", i, vector[i].opaque); } else { - myrows[i] = JByteArray::new(Vec::new()); + // myrows[i] = JByteArray::new(Vec::new()); + myrows[i] = JArrayByte::new(Vec::new()); } info!("Myrow[{}] : {}", i, myrows[i]); } info!("data at {:?}", myrows); JArrayByte2D { len: vlen, - data: myrows, + data: [1;256] } } } From 58f7bf8083406ba15544d7c517c55b4bd1c4ab3f Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 6 Oct 2022 08:57:07 +0200 Subject: [PATCH 31/74] cleanup --- .../tring/TringServiceImpl.java | 52 +++++-------------- src/rust/build.rs | 2 +- src/rust/src/java/java.rs | 12 ++--- src/rust/src/java/jtypes.rs | 8 +-- 4 files changed, 22 insertions(+), 52 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 68780f15..adef056f 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -86,12 +86,12 @@ public void receivedAnswer(String peerId, long callId, int senderDeviceId, int mediaType = 0; long ageSec = 0; this.activeCallId = callId; - LOG.info("Pass received offer to tringlib"); + LOG.info("Pass received answer to tringlib"); tringlib_h.receivedAnswer(callEndpoint, toJString(scope, peerId), callId, senderDeviceId, toJByteArray(scope, senderKey), toJByteArray(scope, receiverKey), - toJByteArray(scope, opaque) - ); + toJByteArray(scope, opaque)); } + public void setSelfUuid(String uuid) { tringlib_h.setSelfUuid(callEndpoint, toJString(scope, uuid)); } @@ -128,10 +128,10 @@ public void hangupCall() { LOG.info("Hangup the call"); tringlib_h.hangupCall(callEndpoint); } - + /** * start a call and return the call_id - * @return a generated call_id + * @return the same call_id as the one we were passed, if success */ @Override public long startOutgoingCall(long callId, String peerId, int localDeviceId) { @@ -281,46 +281,18 @@ Addressable createIceUpdateCallback() { MemorySegment seg = createCallEndpoint$iceUpdateCallback.allocate(sci, scope); return seg.address(); } - + class IceUpdateCallbackImpl implements createCallEndpoint$iceUpdateCallback { + @Override public void apply(MemorySegment icePack) { - byte[] bytes = fromJArrayByte(scope, icePack); - List iceCandidates = new ArrayList<>(); - iceCandidates.add(bytes); - -// long length = JArrayByte2D.len$get(icePack); -// System.err.println("IcePack has "+length+ " ice updates, address at "+icePack); -// List iceCandidates = new ArrayList<>(); -// MemorySegment allData = JArrayByte2D.data$slice(icePack); -// long allSize = allData.byteSize(); -// System.err.println("All size = " + allSize); -// for (int i = 0; i < length; i++) { -// MemorySegment slice = allData.asSlice(8+264*i, 264); -// byte[] rowBytes = fromJArrayByte(scope, slice); -// -// int rowLenght = (int) JArrayByte.len$get(slice); -// JArrayByte. -// int rowLength = (int) JByteArray.len$get(allData, i); -// MemoryAddress rowData = JByteArray.buff$get(allData, i); -// long rawRowAddress = rowData.toRawLongValue(); -// System.err.println("Got length for " + i + ": " + rowLength+", raw address at "+rawRowAddress); -// byte b0 = rowData.get(ValueLayout.JAVA_BYTE, 0); -// byte b1 = rowData.get(ValueLayout.JAVA_BYTE, 1); -// byte b2 = rowData.get(ValueLayout.JAVA_BYTE, 2); -// byte b3 = rowData.get(ValueLayout.JAVA_BYTE, 3); -// System.err.println("b0 = " + b0 + ", b1 = " + b1 + ", b2 = " + b2+", b3 = " + b3); -// byte[] rowBytes = new byte[rowLength]; -// MemorySegment destSegment = MemorySegment.ofArray(rowBytes); -// MemorySegment rowSegment = MemorySegment.ofAddress(rowData, rowLength, scope); -// destSegment.copyFrom(rowSegment); -// System.err.println("ICbytes = " + java.util.Arrays.toString(rowBytes)); -// iceCandidates.add(rowBytes); -// } + byte[] bytes = fromJArrayByte(scope, icePack); + List iceCandidates = new ArrayList<>(); + iceCandidates.add(bytes); + api.iceUpdateCallback(iceCandidates); sendAck(); - System.err.println("TRINGBRIDGE, iceUpdate done!"); - + LOG.info("iceUpdate done!"); } } diff --git a/src/rust/build.rs b/src/rust/build.rs index cbec362b..a59237d1 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("uunable to generate bindings") + .expect("unable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 68a9e21e..d51ee005 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -143,13 +143,11 @@ impl EventReporter { } signaling::Message::Ice(ice) => { info!("[JV] SendSignaling ICE Event"); -let ilen = ice.candidates.len(); - // let icepack: JArrayByte2D = JArrayByte2D::new(ice.candidates); + let ilen = ice.candidates.len(); unsafe { -for i in 0..ilen { - // (self.iceUpdateCallback)(icepack); - (self.iceUpdateCallback)(JArrayByte::new(ice.candidates[i].opaque.clone())); -} + for i in 0..ilen { + (self.iceUpdateCallback)(JArrayByte::new(ice.candidates[i].opaque.clone())); + } } } _ => { @@ -475,7 +473,7 @@ pub unsafe extern "C" fn setSelfUuid(endpoint: i64, ts: JString) -> i64 { let uuid = txt.into_bytes(); let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); callendpoint.call_manager.set_self_uuid(uuid); - 1 + 1 } #[no_mangle] diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index bf5e1fe5..5df39ca3 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -57,21 +57,21 @@ pub struct JArrayByte2D { impl JArrayByte2D { pub fn new(vector: Vec) -> Self { -info!("I have to create a jArrayByte with {} elements" , vector.len()); + info!("I have to create a jArrayByte with {} elements" , vector.len()); let vlen = vector.len(); let mut myrows: [JArrayByte; 25] = [JArrayByte::empty(); 25]; for i in 0..25 { if (i < vlen) { myrows[i] = JArrayByte::new(vector[i].opaque.clone()); // myrows[i] = JByteArray::from_data(vector[i].opaque.as_ptr(), vector[i].opaque.len()); -info!("IceVec[{}] = {:?}", i, vector[i].opaque); + info!("IceVec[{}] = {:?}", i, vector[i].opaque); } else { // myrows[i] = JByteArray::new(Vec::new()); myrows[i] = JArrayByte::new(Vec::new()); } -info!("Myrow[{}] : {}", i, myrows[i]); + info!("Myrow[{}] : {}", i, myrows[i]); } -info!("data at {:?}", myrows); + info!("data at {:?}", myrows); JArrayByte2D { len: vlen, data: [1;256] From ff1fe5862532b61d6c3a2c5e14e47f8da0dbc16b Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 6 Oct 2022 09:15:09 +0200 Subject: [PATCH 32/74] fix fmt --- src/rust/build.rs | 10 +- src/rust/src/java/java.rs | 223 ++++++++++++++++++++++-------------- src/rust/src/java/jtypes.rs | 64 ++++++----- src/rust/src/lib.rs | 1 - 4 files changed, 179 insertions(+), 119 deletions(-) diff --git a/src/rust/build.rs b/src/rust/build.rs index a59237d1..ed156580 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -24,11 +24,11 @@ fn main() { if cfg!(feature = "java") { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); cbindgen::Builder::new() - .with_crate(crate_dir) - .with_language(cbindgen::Language::C) - .generate() - .expect("unable to generate bindings") - .write_to_file("tringlib.h"); + .with_crate(crate_dir) + .with_language(cbindgen::Language::C) + .generate() + .expect("unable to generate bindings") + .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); let profile = env::var("PROFILE").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index d51ee005..bf227c0c 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -11,23 +11,22 @@ use crate::core::call_manager::CallManager; use crate::core::group_call; use crate::core::group_call::{GroupId, SignalingMessageUrgency}; use crate::core::signaling; -use crate::core::util::{ptr_as_mut}; +use crate::core::util::ptr_as_mut; -use crate::java::jtypes::{JString,JArrayByte,JByteArray,JArrayByte2D,JByteArray2D}; +use crate::java::jtypes::{JArrayByte, JArrayByte2D, JByteArray, JByteArray2D, JString}; use crate::lite::http; -use crate::lite::sfu::{UserId}; -use crate::native::{CallState,CallStateHandler,GroupUpdate,GroupUpdateHandler,NativeCallContext,NativePlatform,PeerId,SignalingSender,}; -use crate::webrtc::logging; -use crate::webrtc::media::{ - AudioTrack, VideoFrame, VideoSink, VideoSource, VideoTrack, +use crate::lite::sfu::UserId; +use crate::native::{ + CallState, CallStateHandler, GroupUpdate, GroupUpdateHandler, NativeCallContext, + NativePlatform, PeerId, SignalingSender, }; +use crate::webrtc::logging; +use crate::webrtc::media::{AudioTrack, VideoFrame, VideoSink, VideoSource, VideoTrack}; use crate::webrtc::peer_connection::AudioLevel; -use crate::webrtc::peer_connection_factory::{ - self as pcf, IceServer, PeerConnectionFactory -}; +use crate::webrtc::peer_connection_factory::{self as pcf, IceServer, PeerConnectionFactory}; use crate::webrtc::peer_connection_observer::NetworkRoute; fn init_logging() { @@ -107,11 +106,14 @@ struct EventReporter { } impl EventReporter { - fn new(statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), - answerCallback: extern "C" fn(JArrayByte), - offerCallback: extern "C" fn(JArrayByte), - iceUpdateCallback: extern "C" fn(JArrayByte), - sender: Sender, report: impl Fn() + Send + Sync + 'static) -> Self { + fn new( + statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), + answerCallback: extern "C" fn(JArrayByte), + offerCallback: extern "C" fn(JArrayByte), + iceUpdateCallback: extern "C" fn(JArrayByte), + sender: Sender, + report: impl Fn() + Send + Sync + 'static, + ) -> Self { Self { statusCallback, answerCallback, @@ -123,7 +125,7 @@ impl EventReporter { } fn send(&self, event: Event) -> Result<()> { - match event { + match event { Event::SendSignaling(_peer_id, _maybe_device_id, _call_id, signal) => { info!("[JV] SendSignalingEvent"); match signal { @@ -146,7 +148,9 @@ impl EventReporter { let ilen = ice.candidates.len(); unsafe { for i in 0..ilen { - (self.iceUpdateCallback)(JArrayByte::new(ice.candidates[i].opaque.clone())); + (self.iceUpdateCallback)(JArrayByte::new( + ice.candidates[i].opaque.clone(), + )); } } } @@ -159,14 +163,14 @@ impl EventReporter { info!("[JV] CALLSTATEEVEMNT"); let direction = 0; unsafe { - (self.statusCallback)(call_id, 1,direction, call_media_type); + (self.statusCallback)(call_id, 1, direction, call_media_type); } } Event::CallState(_peer_id, call_id, CallState::Outgoing(call_media_type)) => { info!("[JV] CALLSTATEEVEMNT"); let direction = 1; unsafe { - (self.statusCallback)(call_id, 1,direction, call_media_type); + (self.statusCallback)(call_id, 1, direction, call_media_type); } } Event::CallState(_peer_id, call_id, state) => { @@ -182,7 +186,7 @@ impl EventReporter { }; info!("New state = {} and index = {}", state_string, state_index); unsafe { - (self.statusCallback)(call_id, 1, 10*state_index, CallMediaType::Audio); + (self.statusCallback)(call_id, 1, 10 * state_index, CallMediaType::Audio); } } _ => { @@ -206,7 +210,7 @@ impl SignalingSender for EventReporter { receiver_device_id: Option, msg: signaling::Message, ) -> Result<()> { -info!("Need to send SIGNALING msg {:?}", msg); + info!("Need to send SIGNALING msg {:?}", msg); self.send(Event::SendSignaling( recipient_id.to_string(), receiver_device_id, @@ -252,7 +256,7 @@ impl CallStateHandler for EventReporter { call_id: CallId, call_state: CallState, ) -> Result<()> { -info!("[JV] CallStatehandler, invoke self.send"); + info!("[JV] CallStatehandler, invoke self.send"); self.send(Event::CallState( remote_peer_id.to_string(), @@ -305,7 +309,6 @@ info!("[JV] CallStatehandler, invoke self.send"); } } - impl http::Delegate for EventReporter { fn send_request(&self, request_id: u32, request: http::Request) { let _ = self.send(Event::SendHttpRequest { @@ -361,12 +364,19 @@ impl CallEndpoint { let event_reported = Arc::new(AtomicBool::new(false)); - let event_reporter = EventReporter::new(statusCallback, answerCallback, offerCallback, iceUpdateCallback, events_sender, move || { - info!("[JV] EVENT_REPORTER, NYI"); - if event_reported.swap(true, std::sync::atomic::Ordering::Relaxed) { - return; - } - }); + let event_reporter = EventReporter::new( + statusCallback, + answerCallback, + offerCallback, + iceUpdateCallback, + events_sender, + move || { + info!("[JV] EVENT_REPORTER, NYI"); + if event_reported.swap(true, std::sync::atomic::Ordering::Relaxed) { + return; + } + }, + ); // Only relevant for 1:1 calls let signaling_sender = Box::new(event_reporter.clone()); let should_assume_messages_sent = false; // Use async notification from app to send next message. @@ -427,17 +437,16 @@ impl LastFramesVideoSink { } } - #[no_mangle] pub unsafe extern "C" fn initRingRTC(ts: JString) -> i64 { println!("Initialize RingRTC, init logging"); init_logging(); println!("Initialize RingRTC, init logging done"); -println!("Ready to print {:?}", ts); + println!("Ready to print {:?}", ts); let txt = ts.to_string(); info!("Got text: {}", txt); info!("Initialized RingRTC, using logging"); - 1 + 1 } #[no_mangle] @@ -445,23 +454,31 @@ pub unsafe extern "C" fn getVersion() -> i64 { 1 } - #[no_mangle] -pub unsafe extern "C" fn createCallEndpoint(statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), - answerCallback: extern "C" fn(JArrayByte), - offerCallback: extern "C" fn(JArrayByte), - iceUpdateCallback: extern "C" fn(JArrayByte)) -> i64 { - let call_endpoint = CallEndpoint::new(false, statusCallback, answerCallback, offerCallback, iceUpdateCallback).unwrap(); +pub unsafe extern "C" fn createCallEndpoint( + statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), + answerCallback: extern "C" fn(JArrayByte), + offerCallback: extern "C" fn(JArrayByte), + iceUpdateCallback: extern "C" fn(JArrayByte), +) -> i64 { + let call_endpoint = CallEndpoint::new( + false, + statusCallback, + answerCallback, + offerCallback, + iceUpdateCallback, + ) + .unwrap(); let call_endpoint_box = Box::new(call_endpoint); let boxx: Result<*mut CallEndpoint> = Ok(Box::into_raw(call_endpoint_box)); - let answer: i64 = match boxx { + let answer: i64 = match boxx { Ok(v) => v as i64, Err(e) => { - info!("Error creating callEndpoint: {}", e); + info!("Error creating callEndpoint: {}", e); 0 } - }; + }; info!("[tring] CallEndpoint created at {}", answer); answer } @@ -477,9 +494,18 @@ pub unsafe extern "C" fn setSelfUuid(endpoint: i64, ts: JString) -> i64 { } #[no_mangle] -pub unsafe extern "C" fn receivedOffer(endpoint: i64, peerId: JString, call_id: u64, - offer_type:i32, sender_device_id:u32, receiver_device_id:u32, - sender_key: JByteArray, receiver_key: JByteArray, opaque: JByteArray, age_sec: u64) -> i64 { +pub unsafe extern "C" fn receivedOffer( + endpoint: i64, + peerId: JString, + call_id: u64, + offer_type: i32, + sender_device_id: u32, + receiver_device_id: u32, + sender_key: JByteArray, + receiver_key: JByteArray, + opaque: JByteArray, + age_sec: u64, +) -> i64 { let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let peer_id = JString::from(peerId); let call_id = CallId::new(call_id); @@ -489,44 +515,57 @@ pub unsafe extern "C" fn receivedOffer(endpoint: i64, peerId: JString, call_id: }; let offer = signaling::Offer::new(call_media_type, opaque.to_vec_u8()).unwrap(); callendpoint.call_manager.received_offer( - peer_id.to_string(), - call_id, - signaling::ReceivedOffer { - offer, - age: Duration::from_secs(age_sec), - sender_device_id, - receiver_device_id, - // A Java desktop client cannot be the primary device. - receiver_device_is_primary: false, - sender_identity_key: sender_key.to_vec_u8(), - receiver_identity_key: receiver_key.to_vec_u8(), - }, - ); - 1 + peer_id.to_string(), + call_id, + signaling::ReceivedOffer { + offer, + age: Duration::from_secs(age_sec), + sender_device_id, + receiver_device_id, + // A Java desktop client cannot be the primary device. + receiver_device_is_primary: false, + sender_identity_key: sender_key.to_vec_u8(), + receiver_identity_key: receiver_key.to_vec_u8(), + }, + ); + 1 } #[no_mangle] -pub unsafe extern "C" fn receivedAnswer(endpoint: i64, peerId: JString, call_id: u64, - sender_device_id:u32, sender_key: JByteArray, receiver_key: JByteArray, opaque: JByteArray) -> i64 { +pub unsafe extern "C" fn receivedAnswer( + endpoint: i64, + peerId: JString, + call_id: u64, + sender_device_id: u32, + sender_key: JByteArray, + receiver_key: JByteArray, + opaque: JByteArray, +) -> i64 { let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let peer_id = JString::from(peerId); let call_id = CallId::new(call_id); let answer = signaling::Answer::new(opaque.to_vec_u8()).unwrap(); callendpoint.call_manager.received_answer( - call_id, - signaling::ReceivedAnswer { - answer, - sender_device_id, - sender_identity_key: sender_key.to_vec_u8(), - receiver_identity_key: receiver_key.to_vec_u8(), - }, - ); - 1 + call_id, + signaling::ReceivedAnswer { + answer, + sender_device_id, + sender_identity_key: sender_key.to_vec_u8(), + receiver_identity_key: receiver_key.to_vec_u8(), + }, + ); + 1 } // suppy a random callid #[no_mangle] -pub unsafe extern "C" fn createOutgoingCall(endpoint: i64, peer_id: JString, video_enabled: bool, local_device_id:u32, call_id: i64) -> i64 { +pub unsafe extern "C" fn createOutgoingCall( + endpoint: i64, + peer_id: JString, + video_enabled: bool, + local_device_id: u32, + call_id: i64, +) -> i64 { info!("create outgoing call"); let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let peer_id = peer_id.to_string(); @@ -536,17 +575,19 @@ pub unsafe extern "C" fn createOutgoingCall(endpoint: i64, peer_id: JString, vid CallMediaType::Audio }; let call_id = CallId::from(call_id); - endpoint.call_manager.create_outgoing_call( - peer_id, - call_id, - media_type, - local_device_id, - ); + endpoint + .call_manager + .create_outgoing_call(peer_id, call_id, media_type, local_device_id); 1 } #[no_mangle] -pub unsafe extern "C" fn proceedCall(endpoint: i64, call_id: u64, bandwidth_mode: i32, audio_levels_interval_millis:i32) -> i64 { +pub unsafe extern "C" fn proceedCall( + endpoint: i64, + call_id: u64, + bandwidth_mode: i32, + audio_levels_interval_millis: i32, +) -> i64 { info!("Proceeding with call"); let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let call_id = CallId::from(call_id); @@ -567,14 +608,20 @@ pub unsafe extern "C" fn proceedCall(endpoint: i64, call_id: u64, bandwidth_mode call_id, context, BandwidthMode::from_i32(bandwidth_mode), - audio_levels_interval); + audio_levels_interval, + ); 147 } #[no_mangle] -pub unsafe extern "C" fn receivedIce(endpoint: i64, call_id: u64, sender_device_id: DeviceId, icepack: JByteArray2D) { - info!("JavaRing, received_ice with length = {}", icepack.len ); +pub unsafe extern "C" fn receivedIce( + endpoint: i64, + call_id: u64, + sender_device_id: DeviceId, + icepack: JByteArray2D, +) { + info!("JavaRing, received_ice with length = {}", icepack.len); let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); info!("Received offer, endpoint = {:?}", endpoint); let call_id = CallId::from(call_id); @@ -583,7 +630,7 @@ pub unsafe extern "C" fn receivedIce(endpoint: i64, call_id: u64, sender_device_ let row = &icepack.buff[j]; let opaque = row.to_vec_u8(); ice_candidates.push(signaling::IceCandidate::new(opaque)); - } + } callendpoint.call_manager.received_ice( call_id, signaling::ReceivedIce { @@ -601,7 +648,7 @@ pub unsafe extern "C" fn acceptCall(endpoint: i64, call_id: u64) -> i64 { info!("now accept call"); let call_id = CallId::from(call_id); endpoint.call_manager.accept_call(call_id); - 573 + 573 } #[no_mangle] @@ -626,14 +673,16 @@ pub unsafe extern "C" fn signalMessageSent(endpoint: i64, call_id: CallId) -> i6 let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); info!("Received signalmessagesent, endpoint = {:?}", endpoint); callendpoint.call_manager.message_sent(call_id); - 135 + 135 } #[no_mangle] pub unsafe extern "C" fn setAudioInput(endpoint: i64, index: u16) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); info!("Have to set audio_recordig_device to {}", index); - endpoint.peer_connection_factory.set_audio_recording_device(index); + endpoint + .peer_connection_factory + .set_audio_recording_device(index); 1 } @@ -641,7 +690,9 @@ pub unsafe extern "C" fn setAudioInput(endpoint: i64, index: u16) -> i64 { pub unsafe extern "C" fn setAudioOutput(endpoint: i64, index: u16) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); info!("Have to set audio_output_device to {}", index); - endpoint.peer_connection_factory.set_audio_playout_device(index); + endpoint + .peer_connection_factory + .set_audio_playout_device(index); 1 } @@ -652,5 +703,3 @@ pub unsafe extern "C" fn setOutgoingAudioEnabled(endpoint: i64, enable: bool) -> endpoint.outgoing_audio_track.set_enabled(enable); 1 } - - diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index 5df39ca3..9e55ebf2 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -1,8 +1,7 @@ -use core::slice; use crate::core::signaling; +use core::slice; use std::fmt; - #[repr(C)] #[derive(Debug)] pub struct JString { @@ -10,7 +9,6 @@ pub struct JString { buff: *mut u8, } - impl JString { pub fn to_string(&self) -> String { let answer = unsafe { String::from_raw_parts(self.buff, self.len, self.len) }; @@ -20,33 +18,39 @@ impl JString { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct JArrayByte { - pub len: usize, - pub data: [u8; 256], + pub len: usize, + pub data: [u8; 256], } impl fmt::Display for JArrayByte { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "JArrayByte with {} bytes at {:?}", self.len, &(self.data)) + write!( + f, + "JArrayByte with {} bytes at {:?}", + self.len, + &(self.data) + ) } } impl JArrayByte { - pub fn new(vector: Vec ) -> Self { + pub fn new(vector: Vec) -> Self { let vlen = vector.len(); - let mut vdata= [0; 256]; + let mut vdata = [0; 256]; for i in 0..vlen { vdata[i] = vector[i]; } - JArrayByte{len:vlen, data:vdata} - } + JArrayByte { + len: vlen, + data: vdata, + } + } pub fn empty() -> Self { - let data = [0;256]; - JArrayByte{len: 0, data: data} - } - + let data = [0; 256]; + JArrayByte { len: 0, data: data } + } } - #[repr(C)] #[derive(Debug)] pub struct JArrayByte2D { @@ -57,7 +61,10 @@ pub struct JArrayByte2D { impl JArrayByte2D { pub fn new(vector: Vec) -> Self { - info!("I have to create a jArrayByte with {} elements" , vector.len()); + info!( + "I have to create a jArrayByte with {} elements", + vector.len() + ); let vlen = vector.len(); let mut myrows: [JArrayByte; 25] = [JArrayByte::empty(); 25]; for i in 0..25 { @@ -74,12 +81,11 @@ impl JArrayByte2D { info!("data at {:?}", myrows); JArrayByte2D { len: vlen, - data: [1;256] + data: [1; 256], } - } + } } - #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct JByteArray { @@ -98,7 +104,10 @@ impl JByteArray { pub fn new(vector: Vec) -> Self { let slice = vector.as_slice(); let buffer = slice.as_ptr(); - JByteArray{len: vector.len(), buff: buffer} + JByteArray { + len: vector.len(), + buff: buffer, + } } pub fn to_vec_u8(&self) -> Vec { @@ -108,20 +117,22 @@ impl JByteArray { pub fn empty() -> Self { let bar = Vec::new().as_ptr(); - JByteArray{len: 0, buff: bar} + JByteArray { len: 0, buff: bar } } pub fn from_data(data: *const u8, len: usize) -> Self { - JByteArray{len: len, buff: data} + JByteArray { + len: len, + buff: data, + } } - } #[repr(C)] #[derive(Debug)] pub struct JByteArray2D { pub len: usize, - pub buff: [JByteArray;32], + pub buff: [JByteArray; 32], } impl JByteArray2D { @@ -131,7 +142,8 @@ impl JByteArray2D { let mut myrows: [JByteArray; 32] = [JByteArray::empty(); 32]; for i in 0..25 { if (i < vlen) { - myrows[i] = JByteArray::from_data(vector[i].opaque.as_ptr(), vector[i].opaque.len()); + myrows[i] = + JByteArray::from_data(vector[i].opaque.as_ptr(), vector[i].opaque.len()); } else { myrows[i] = JByteArray::new(Vec::new()); } @@ -140,5 +152,5 @@ impl JByteArray2D { len: vlen, buff: myrows, } - } + } } diff --git a/src/rust/src/lib.rs b/src/rust/src/lib.rs index 1453e10a..134ed48a 100644 --- a/src/rust/src/lib.rs +++ b/src/rust/src/lib.rs @@ -153,4 +153,3 @@ pub mod sim { pub mod simnet { pub mod router; } - From eb5a57297add5179dba16ec12f8193b0f6257865 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 6 Oct 2022 10:49:39 +0200 Subject: [PATCH 33/74] changes to build 0.0.2 (tringapi) and 0.0.5 (tring) --- src/java/tring/pom.xml | 2 +- src/java/tringapi/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 03ad85f9..fae46eed 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.5-SNAPSHOT + 0.0.5 jar UTF-8 diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index acfd9c38..a7938868 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.2-SNAPSHOT + 0.0.2 jar UTF-8 From f5f5375bf47ee0534c121b6f3507ba9b58e065f6 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 6 Oct 2022 11:25:47 +0200 Subject: [PATCH 34/74] Tring should depend on a release of TringApi if we want to release Tring --- src/java/tring/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index fae46eed..26ff6bfb 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.2-SNAPSHOT + 0.0.2 From 9d1a9bf61ed156184c8677834d52b8c3bd6657f1 Mon Sep 17 00:00:00 2001 From: "jose.pereda" Date: Thu, 6 Oct 2022 14:33:30 +0200 Subject: [PATCH 35/74] Use service loader pre JPMS --- .../java/io/privacyresearch/tring/TringServiceImpl.java | 9 +++++---- .../services/io.privacyresearch.tringapi.TringService | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 src/java/tring/src/main/resources/META-INF/services/io.privacyresearch.tringapi.TringService diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index adef056f..78c4f35b 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -38,6 +38,11 @@ public class TringServiceImpl implements TringService { } } + + public TringServiceImpl() { + // no-op + } + public static TringService provider() { return instance; } @@ -50,10 +55,6 @@ public static long getNativeVersion() { return nativeVersion; } - protected TringServiceImpl() { - - } - @Override public void setApi(io.privacyresearch.tringapi.TringApi api) { this.api = api; diff --git a/src/java/tring/src/main/resources/META-INF/services/io.privacyresearch.tringapi.TringService b/src/java/tring/src/main/resources/META-INF/services/io.privacyresearch.tringapi.TringService new file mode 100644 index 00000000..6202e88e --- /dev/null +++ b/src/java/tring/src/main/resources/META-INF/services/io.privacyresearch.tringapi.TringService @@ -0,0 +1 @@ +io.privacyresearch.tring.TringServiceImpl From 2bfc32eb5ac51858305a5f8f795cc481c03ffebd Mon Sep 17 00:00:00 2001 From: "jose.pereda" Date: Thu, 6 Oct 2022 14:44:40 +0200 Subject: [PATCH 36/74] Use gen-sources --- .gitignore | 5 ++++- bin/build-java | 3 +-- src/java/tring/pom.xml | 22 ++++++++++++++++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 7b98724a..3736b890 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,8 @@ src/jar.list .classpath org.eclipse.buildship.core.prefs src/java/build +src/java/tring/src/gen-sources +src/java/tring/src/main/resources/libringrtc.dylib src/java/tring/target -/src/java/tringapi/target/ +src/java/tringapi/target/ +src/rust/tringlib.h diff --git a/bin/build-java b/bin/build-java index 62cf589e..4789cef7 100755 --- a/bin/build-java +++ b/bin/build-java @@ -142,8 +142,7 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" mkdir -p ../java/build/darwin cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/tring/src/main/resources/libringrtc.dylib # cp -f target/${CARGO_TARGET}/${BUILD_TYPE}/libringrtc.dylib ../java/build/darwin/libringrtc-"${TARGET_ARCH}" - ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/darwin -I${MACOS_SDK_PATH}/usr/include --output ../java/tring/src/main/java --source -t io.privacyresearch.tring tringlib.h - ARCH_CLASSIFIER="x86_64" + ${JEXTRACT}/bin/jextract -I${JDK}include -I${JDK}/include/darwin -I${MACOS_SDK_PATH}/usr/include --output ../java/tring/src/gen-sources/java --source -t io.privacyresearch.tring tringlib.h elif [ $DEFAULT_PLATFORM = "win32" ] then mkdir -p ../java/build/win32 diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 26ff6bfb..7662fb8c 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -25,11 +25,29 @@ 3.8.1 - --enable-preview - + --enable-preview + + + org.codehaus.mojo + build-helper-maven-plugin + 3.3.0 + + + generate-sources + + add-source + + + + src/gen-sources + + + + + org.apache.maven.plugins maven-surefire-plugin From a995c4a35ec689a5a60fa6572c4be493a4e192dd Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 6 Oct 2022 15:24:06 +0200 Subject: [PATCH 37/74] Bump tringapi version (before bunping the tring version); --- src/java/tringapi/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index a7938868..a49b4ef8 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.2 + 0.0.3-SNAPSHOT jar UTF-8 From eb50ba4c3cd048cd7c564125514ad1dfb191b281 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 6 Oct 2022 15:24:57 +0200 Subject: [PATCH 38/74] And then bump tring version --- src/java/tring/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 26ff6bfb..071c6761 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.5 + 0.0.6-SNAPSHOT jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.2 + 0.0.3-SNAPSHOT From 51442f3c8d0a2ad850c160ba5a25e364689dd813 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 7 Oct 2022 10:49:08 +0200 Subject: [PATCH 39/74] Pass STUN/TURN server info via proceedcall --- .../privacyresearch/tring/OldTringBridge.java | 65 ++++++++++--------- .../tring/TringServiceImpl.java | 6 +- .../privacyresearch/tringapi/TringBridge.java | 7 +- .../tringapi/TringService.java | 2 +- src/rust/src/java/java.rs | 11 +++- 5 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringBridge.java b/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringBridge.java index 3e0acac9..7cbc3c98 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringBridge.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/OldTringBridge.java @@ -1,11 +1,11 @@ package io.privacyresearch.tring; -import io.privacyresearch.tringapi.TringApi; -import io.privacyresearch.tringapi.TringService; - -import java.util.List; -import java.util.Optional; -import java.util.ServiceLoader; +//import io.privacyresearch.tringapi.TringApi; +//import io.privacyresearch.tringapi.TringService; +// +//import java.util.List; +//import java.util.Optional; +//import java.util.ServiceLoader; /** * @@ -13,31 +13,32 @@ */ @Deprecated public class OldTringBridge { - - private TringService service; - - public OldTringBridge(TringApi api) { - ServiceLoader loader = ServiceLoader.load(TringService.class); - Optional serviceOpt = loader.findFirst(); - this.service = serviceOpt.get(); - this.service.setApi(api); - } - - public void acceptCall() { - service.acceptCall(); - } - - public void proceed(long callId) { - service.proceed(callId); - } - - public void receivedIce(long callId, int senderDeviceId, List ice) { - receivedIce(callId, senderDeviceId, ice); - } - - public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, - byte[] senderKey, byte[] receiverKey, byte[] opaque) { - receivedOffer(peerId, callId, senderDeviceId, receiverDeviceId, senderKey, receiverKey, opaque); - } + // ready to be removed in next commit +// +// private TringService service; +// +// public OldTringBridge(TringApi api) { +// ServiceLoader loader = ServiceLoader.load(TringService.class); +// Optional serviceOpt = loader.findFirst(); +// this.service = serviceOpt.get(); +// this.service.setApi(api); +// } +// +// public void acceptCall() { +// service.acceptCall(); +// } +// +// public void proceed(long callId) { +// service.proceed(callId); +// } +// +// public void receivedIce(long callId, int senderDeviceId, List ice) { +// receivedIce(callId, senderDeviceId, ice); +// } +// +// public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, +// byte[] senderKey, byte[] receiverKey, byte[] opaque) { +// receivedOffer(peerId, callId, senderDeviceId, receiverDeviceId, senderKey, receiverKey, opaque); +// } } diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 78c4f35b..79a671f6 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -98,8 +98,10 @@ public void setSelfUuid(String uuid) { } @Override - public void proceed(long callId) { - tringlib_h.proceedCall(callEndpoint, callId, 0, 0); + public void proceed(long callId, String iceUser, String icePwd, List ice) { + MemorySegment icePack = toJByteArray2D(scope, ice); + tringlib_h.proceedCall(callEndpoint, callId, 0, 0, + toJString(scope, iceUser), toJString(scope, icePwd), icePack); } @Override diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index cd8ca217..5485cc98 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -1,9 +1,11 @@ package io.privacyresearch.tringapi; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Optional; import java.util.ServiceLoader; import java.util.logging.Logger; +import java.util.stream.Collectors; /** * This class provides the access points for the application to interact with @@ -50,8 +52,9 @@ public void hangupCall() { service.hangupCall(); } - public void proceed(long callId) { - service.proceed(callId); + public void proceed(long callId, String iceUser, String icePassword, List ice) { + List iceb = ice.stream().map(s -> s.getBytes(StandardCharsets.UTF_8)).collect(Collectors.toList()); + service.proceed(callId, iceUser, icePassword, iceb); } public void receivedIce(long callId, int senderDeviceId, List ice) { diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index 0026e321..d9b56364 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -18,7 +18,7 @@ public interface TringService { public void ignoreCall(); public void hangupCall(); - public void proceed(long callId); + public void proceed(long callId, String iceUser, String icePwd, List ice); public void receivedIce(long callId, int senderDeviceId, List ice); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index bf227c0c..3c4bec5d 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -587,11 +587,20 @@ pub unsafe extern "C" fn proceedCall( call_id: u64, bandwidth_mode: i32, audio_levels_interval_millis: i32, + ice_user: JString, + ice_pwd: JString, + icepack: JByteArray2D, ) -> i64 { info!("Proceeding with call"); let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let call_id = CallId::from(call_id); - let ice_server = IceServer::new(String::from("iceuser"), String::from("icepwd"), Vec::new()); + let mut ice_candidates = Vec::new(); + for j in 0..icepack.len { + let row = &icepack.buff[j]; + let opaque = row.to_vec_u8(); + ice_candidates.push(String::from_utf8(opaque).unwrap()); + } + let ice_server = IceServer::new(ice_user.to_string(), ice_pwd.to_string(), ice_candidates); let context = NativeCallContext::new( false, ice_server, From 07ee582e1e785e0c5388197bc4e4e46e0902681f Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 7 Oct 2022 12:21:02 +0200 Subject: [PATCH 40/74] build 0.0.3 --- src/java/tringapi/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index a49b4ef8..ff15f887 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.3-SNAPSHOT + 0.0.3 jar UTF-8 From c32429b877edc8cf517ed65b70817f6457557090 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 7 Oct 2022 12:22:12 +0200 Subject: [PATCH 41/74] build 0.0.6 with api 0.0.3 --- src/java/tring/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 265ed97d..4045ebcb 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.6-SNAPSHOT + 0.0.6 jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.3-SNAPSHOT + 0.0.3 From c10327cc10fdeedc9e7928b969008829b72191b7 Mon Sep 17 00:00:00 2001 From: Abhinay Agarwal Date: Fri, 7 Oct 2022 23:56:45 +0530 Subject: [PATCH 42/74] Add workflow to build and release snapshots --- .github/workflows/build.yml | 89 +++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..34198dad --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,89 @@ +name: Build and publish snapshots +on: + push: + branches: [ add-workflow ] + +jobs: + build: + strategy: + matrix: + os: [ ubuntu-latest, macos-latest ] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + with: + ref: javabuild + - name: Install latest bash on macOS + if: runner.os == 'macOS' + run: | + brew update + brew install bash + brew install coreutils + - name: Set environment variables + run: | + echo "OS=${RUNNER_OS,,}" >> $GITHUB_ENV + echo "ARCH=${RUNNER_ARCH,,}" >> $GITHUB_ENV + if [[ ${{ runner.os }} == "Linux" ]] + then + platform=unix + classifier=linux-x86_64 + elif [[ ${{ runner.os }} == "macOS" ]] + then + platform=mac + if [[ ${{ runner.arch }} == "X64" ]] + then + classifier=darwin-x86_64 + else + classifier=darwin-aarch64 + fi + elif [[ ${{ runner.os }} == "Windows" ]] + then + platform=windows + classifier=win-x86_64 + fi + echo "PLATFORM=$platform" >> $GITHUB_ENV + echo "CLASSIFIER=$classifier" >> $GITHUB_ENV + shell: bash + - name: Download OpenJDK 19 + id: download + uses: oracle-actions/setup-java@v1 + with: + website: jdk.java.net + release: 19 + install: false + - name: Setup Java and Apache Maven + uses: actions/setup-java@v3 + with: + distribution: jdkfile + jdkFile: ${{ steps.download.outputs.archive }} + java-version: ${{ steps.download.outputs.version }} + server-id: gluon-nexus + server-username: MAVEN_USERNAME + server-password: MAVEN_CENTRAL_TOKEN + - name: Checkout tools repo + run: | + echo "print env variables" + echo ${{ env.OS }} + echo ${{ env.ARCH }} + echo ${{ env.PLATFORM }} + echo ${{ env.CLASSIFIER }} + cd $GITHUB_WORKSPACE + git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git + - name: Install rustup + run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + - name: Download and extract JEXTRACT + run: | + download_url="https://download.java.net/java/early_access/jextract/2/openjdk-19-jextract+2-3_${{ env.OS }}-${{ env.ARCH }}_bin.tar.gz" + wget -q --show-progress -O $RUNNER_TEMP/jextract.tar.gz $download_url + tar -xvzf $RUNNER_TEMP/jextract.tar.gz -C $GITHUB_WORKSPACE + - name: Build + run: | + export PATH=$GITHUB_WORKSPACE/depot_tools/:$PATH + make java PLATFORM=${{ env.PLATFORM }} JEXTRACT=$GITHUB_WORKSPACE/jextract-19 JDK=$JAVA_HOME TARGET_ARCH=${{ env.ARCH }} MACOS_SDK_VERSION=12.1 + - name: Deploy snapshot + run: | + cd src/java/tring + mvn -Dclassifier=${{ env.CLASSIFIER }} deploy + env: + MAVEN_USERNAME: ${{ secrets.GLUON_NEXUS_USERNAME }} + MAVEN_CENTRAL_TOKEN: ${{ secrets.GLUON_NEXUS_PASSWORD }} \ No newline at end of file From 502460309d60b8acd4fff699687d8ce999e80e00 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 7 Oct 2022 20:26:58 +0200 Subject: [PATCH 43/74] Allow to handle Hangup callbacks --- src/rust/src/java/java.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 3c4bec5d..19b5f1a9 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -97,7 +97,7 @@ pub enum Event { #[repr(C)] #[allow(non_snake_case)] struct EventReporter { - pub statusCallback: unsafe extern "C" fn(CallId, u64, i32, CallMediaType), + pub statusCallback: unsafe extern "C" fn(CallId, u64, i32, i32), pub answerCallback: unsafe extern "C" fn(JArrayByte), pub offerCallback: unsafe extern "C" fn(JArrayByte), pub iceUpdateCallback: unsafe extern "C" fn(JArrayByte), @@ -107,7 +107,7 @@ struct EventReporter { impl EventReporter { fn new( - statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), + statusCallback: extern "C" fn(CallId, u64, i32, i32), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), @@ -126,7 +126,7 @@ impl EventReporter { fn send(&self, event: Event) -> Result<()> { match event { - Event::SendSignaling(_peer_id, _maybe_device_id, _call_id, signal) => { + Event::SendSignaling(_peer_id, _maybe_device_id, call_id, signal) => { info!("[JV] SendSignalingEvent"); match signal { signaling::Message::Offer(offer) => { @@ -154,6 +154,13 @@ impl EventReporter { } } } + signaling::Message::Hangup(hangup) => { + let (hangup_type, hangup_device_id) = hangup.to_type_and_device_id(); + info!("[JV] SendSignaling Hangup Event"); + unsafe { + (self.statusCallback)(call_id, hangup_device_id.unwrap().into(), 11, hangup_type as i32); + } + } _ => { info!("[JV] unknownSendSignalingEvent WHICH IS WHAT WE NEED TO FIX NOW!"); } @@ -163,14 +170,14 @@ impl EventReporter { info!("[JV] CALLSTATEEVEMNT"); let direction = 0; unsafe { - (self.statusCallback)(call_id, 1, direction, call_media_type); + (self.statusCallback)(call_id, 1, direction, call_media_type as i32); } } Event::CallState(_peer_id, call_id, CallState::Outgoing(call_media_type)) => { info!("[JV] CALLSTATEEVEMNT"); let direction = 1; unsafe { - (self.statusCallback)(call_id, 1, direction, call_media_type); + (self.statusCallback)(call_id, 1, direction, call_media_type as i32); } } Event::CallState(_peer_id, call_id, state) => { @@ -186,7 +193,7 @@ impl EventReporter { }; info!("New state = {} and index = {}", state_string, state_index); unsafe { - (self.statusCallback)(call_id, 1, 10 * state_index, CallMediaType::Audio); + (self.statusCallback)(call_id, 1, 10 * state_index, 0); } } _ => { @@ -343,7 +350,7 @@ pub struct CallEndpoint { impl CallEndpoint { fn new<'a>( use_new_audio_device_module: bool, - statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), + statusCallback: extern "C" fn(CallId, u64, i32, i32), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), @@ -456,7 +463,7 @@ pub unsafe extern "C" fn getVersion() -> i64 { #[no_mangle] pub unsafe extern "C" fn createCallEndpoint( - statusCallback: extern "C" fn(CallId, u64, i32, CallMediaType), + statusCallback: extern "C" fn(CallId, u64, i32, i32), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), From 3c297b8aff35734e0b6e28b39d531ba37ffb885a Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 7 Oct 2022 20:32:32 +0200 Subject: [PATCH 44/74] fix formatting --- src/rust/src/java/java.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 19b5f1a9..35368e85 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -158,7 +158,12 @@ impl EventReporter { let (hangup_type, hangup_device_id) = hangup.to_type_and_device_id(); info!("[JV] SendSignaling Hangup Event"); unsafe { - (self.statusCallback)(call_id, hangup_device_id.unwrap().into(), 11, hangup_type as i32); + (self.statusCallback)( + call_id, + hangup_device_id.unwrap().into(), + 11, + hangup_type as i32, + ); } } _ => { From 3e7a09dbfab727bd7d143bcdc06d301b5774e9c5 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 7 Oct 2022 20:32:41 +0200 Subject: [PATCH 45/74] bump maven versions --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 4045ebcb..ae7e666c 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.6 + 0.0.7-SNAPSHOT jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.3 + 0.0.3-SNAPSHOT diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index ff15f887..a49b4ef8 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.3 + 0.0.3-SNAPSHOT jar UTF-8 From f59febc03e3100e7bd5729bf68d5163ba8556150 Mon Sep 17 00:00:00 2001 From: Abhinay Agarwal Date: Sat, 8 Oct 2022 00:13:53 +0530 Subject: [PATCH 46/74] Run for every commit of javabuild branch --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 34198dad..657a13cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,7 +1,7 @@ name: Build and publish snapshots on: push: - branches: [ add-workflow ] + branches: [ javabuild ] jobs: build: From f5fe559caa1128043e26e88aa088b60c4a13571a Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 7 Oct 2022 20:55:25 +0200 Subject: [PATCH 47/74] increase version instead of decreasing it! --- src/java/tring/pom.xml | 2 +- src/java/tringapi/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index ae7e666c..7847af3d 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.3-SNAPSHOT + 0.0.4-SNAPSHOT diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index a49b4ef8..388dac25 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.3-SNAPSHOT + 0.0.4-SNAPSHOT jar UTF-8 From 4bfdf1455d4689e2a4d032726e79b44a9313521e Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sat, 8 Oct 2022 21:32:45 +0200 Subject: [PATCH 48/74] build tringapi 0.0.4 with tring 0.0.7 --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 7847af3d..05117fe2 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.7-SNAPSHOT + 0.0.7 jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.4-SNAPSHOT + 0.0.4 diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index 388dac25..dd5ae028 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.4-SNAPSHOT + 0.0.4 jar UTF-8 From d1a5bdb08d3158842b0bb1c76070a50d9d91dcd3 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 28 Nov 2022 11:59:51 +0100 Subject: [PATCH 49/74] Hardcode device 1 --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- src/rust/src/java/java.rs | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 05117fe2..beb10139 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.7 + 0.0.8-SNAPSHOT jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.4 + 0.0.5-SNAPSHOT diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index dd5ae028..faf5c496 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.4 + 0.0.5-SNAPSHOT jar UTF-8 diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 35368e85..213109fd 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -160,7 +160,8 @@ impl EventReporter { unsafe { (self.statusCallback)( call_id, - hangup_device_id.unwrap().into(), + 1, + // hangup_device_id.unwrap().into(), 11, hangup_type as i32, ); From 78c0a59b64393e8ed8d259272953b9962418b3f2 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 4 Dec 2022 17:28:51 +0100 Subject: [PATCH 50/74] Add video functionality --- .../tring/TringServiceImpl.java | 46 +++++++- .../io/privacyresearch/tringapi/TringApi.java | 2 + .../privacyresearch/tringapi/TringBridge.java | 12 ++ .../tringapi/TringService.java | 9 ++ src/rust/build.rs | 2 +- src/rust/src/core/connection.rs | 1 + src/rust/src/java/java.rs | 108 +++++++++++++++--- src/rust/src/java/jtypes.rs | 8 ++ 8 files changed, 170 insertions(+), 18 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 79a671f6..5450190c 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -65,7 +65,8 @@ private void initiate() { scope = MemorySession.openShared(); tringlib_h.initRingRTC(toJString(scope, "Hello from Java")); this.callEndpoint = tringlib_h.createCallEndpoint(createStatusCallback(), - createAnswerCallback(), createOfferCallback(), createIceUpdateCallback()); + createAnswerCallback(), createOfferCallback(), createIceUpdateCallback(), + createVideoFrameCallback()); } @Override @@ -118,6 +119,7 @@ public void acceptCall() { tringlib_h.setOutgoingAudioEnabled(callEndpoint, true); LOG.info("And now accept the call"); tringlib_h.acceptCall(callEndpoint, activeCallId); + LOG.info("Accepted the call"); } @Override @@ -145,6 +147,23 @@ public long startOutgoingCall(long callId, String peerId, int localDeviceId) { return callId; } + @Override + public byte[] getRemoteVideoFrame() { + long a= tringlib_h.retrieveRemoteVideoFrame(callEndpoint); + return null; + } + + @Override + public void enableOutgoingVideo(boolean enable) { + tringlib_h.setOutgoingVideoEnabled(callEndpoint, enable); + } + + @Override + public void sendVideoFrame(int w, int h, byte[] raw) { + MemorySegment buff = scope.allocateArray(ValueLayout.JAVA_BYTE, raw); + tringlib_h.sendVideoFrame(callEndpoint, w, h, 1, buff); + } + static MemorySegment toJByteArray2D(MemorySession ms, List rows) { MemorySegment answer = JByteArray2D.allocate(ms); JByteArray2D.len$set(answer, rows.size()); @@ -237,8 +256,8 @@ Addressable createStatusCallback() { class StatusCallbackImpl implements createCallEndpoint$statusCallback { @Override - public void apply(MemorySegment callId, long _x1, int direction, int type) { - long id = CallId.id$get(callId); + public void apply(long id, long _x1, int direction, int type) { + // long id = CallId.id$get(callId); api.statusCallback(id, _x1, direction, type); } } @@ -299,9 +318,30 @@ public void apply(MemorySegment icePack) { } } + Addressable createVideoFrameCallback() { + VideoFrameCallbackImpl sci = new VideoFrameCallbackImpl(); + MemorySegment seg = createCallEndpoint$videoFrameCallback.allocate(sci, scope); + return seg.address(); + } + + class VideoFrameCallbackImpl implements createCallEndpoint$videoFrameCallback { + @Override + public void apply(MemoryAddress opaque, int w, int h, long size) { + System.err.println("TRINGBRIDGE, send video data!"); + System.err.println("TRING, videobytessize = "+size); + MemorySegment segment = MemorySegment.ofAddress(opaque, size, scope); + System.err.println("got segment = "+ segment); + byte[] raw = segment.toArray(ValueLayout.JAVA_BYTE); + api.getVideoFrame(w, h, raw); + sendAck(); + System.err.println("TRING, ack sent for videoframe"); + } + } + void sendAck() { MemorySegment callid = MemorySegment.allocateNative(8, scope); callid.set(ValueLayout.JAVA_LONG, 0l, activeCallId); tringlib_h.signalMessageSent(callEndpoint, callid); } + } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java index 71175b6a..49b6b4c3 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java @@ -16,4 +16,6 @@ public interface TringApi { void iceUpdateCallback(List iceCandidates); + void getVideoFrame(int w, int h, byte[] raw); + } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index 5485cc98..bbccbd2d 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -75,4 +75,16 @@ public long startOutgoingCall(long callId, String peerId, int localDeviceId) { return service.startOutgoingCall(callId, peerId, localDeviceId); } + public void enableOutgoingVideo(boolean enable) { + service.enableOutgoingVideo(enable); + } + + public byte[] getRemoteVideoFrame() { + return service.getRemoteVideoFrame(); + } + + public void sendVideoFrame(int width, int height, byte[] raw) { + service.sendVideoFrame(width, width, raw); + } + } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index d9b56364..1d850170 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -33,4 +33,13 @@ public default String getVersionInfo() { return "Unresolved TringService"; } + /** + * Disable or enable outgoing video. + * @param enable true if we want to enable outgoing video, false otherwise + */ + public void enableOutgoingVideo(boolean enable); + + public byte[] getRemoteVideoFrame(); + public void sendVideoFrame(int w, int h, byte[] raw); + } diff --git a/src/rust/build.rs b/src/rust/build.rs index ed156580..58299457 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("unable to generate bindings") + .expect("uuunable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/core/connection.rs b/src/rust/src/core/connection.rs index 3ff2877a..2e4c4511 100644 --- a/src/rust/src/core/connection.rs +++ b/src/rust/src/core/connection.rs @@ -2061,6 +2061,7 @@ where _video_frame_metadata: VideoFrameMetadata, video_frame: Option, ) -> Result<()> { +info!("Hello, incoming video frame"); if let (Some(incoming_video_sink), Some(video_frame)) = (self.incoming_video_sink.as_ref(), video_frame) { diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 213109fd..a89e3311 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -1,10 +1,15 @@ +#![allow(unused_parens)] + use std::collections::HashMap; +use std::slice; use std::sync::atomic::AtomicBool; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; use std::time::Duration; +use libc::size_t; + use crate::common::{CallDirection, CallId, CallMediaType, DeviceId, Result}; use crate::core::bandwidth_mode::BandwidthMode; use crate::core::call_manager::CallManager; @@ -22,7 +27,7 @@ use crate::native::{ NativePlatform, PeerId, SignalingSender, }; use crate::webrtc::logging; -use crate::webrtc::media::{AudioTrack, VideoFrame, VideoSink, VideoSource, VideoTrack}; +use crate::webrtc::media::{AudioTrack, VideoFrame, VideoPixelFormat, VideoSink, VideoSource, VideoTrack}; use crate::webrtc::peer_connection::AudioLevel; @@ -97,7 +102,7 @@ pub enum Event { #[repr(C)] #[allow(non_snake_case)] struct EventReporter { - pub statusCallback: unsafe extern "C" fn(CallId, u64, i32, i32), + pub statusCallback: unsafe extern "C" fn(u64, u64, i32, i32), pub answerCallback: unsafe extern "C" fn(JArrayByte), pub offerCallback: unsafe extern "C" fn(JArrayByte), pub iceUpdateCallback: unsafe extern "C" fn(JArrayByte), @@ -107,7 +112,7 @@ struct EventReporter { impl EventReporter { fn new( - statusCallback: extern "C" fn(CallId, u64, i32, i32), + statusCallback: extern "C" fn(u64, u64, i32, i32), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), @@ -127,10 +132,10 @@ impl EventReporter { fn send(&self, event: Event) -> Result<()> { match event { Event::SendSignaling(_peer_id, _maybe_device_id, call_id, signal) => { - info!("[JV] SendSignalingEvent"); + info!("JavaPlatform needs to send SignalingEvent to app"); match signal { signaling::Message::Offer(offer) => { - info!("[JV] SendSignaling OFFER Event"); + info!("[JV] SendSignaling OFFER Event and call_id = {}", call_id.as_u64()); let op = JArrayByte::new(offer.opaque); unsafe { (self.offerCallback)(op); @@ -159,7 +164,7 @@ impl EventReporter { info!("[JV] SendSignaling Hangup Event"); unsafe { (self.statusCallback)( - call_id, + call_id.as_u64(), 1, // hangup_device_id.unwrap().into(), 11, @@ -171,19 +176,20 @@ impl EventReporter { info!("[JV] unknownSendSignalingEvent WHICH IS WHAT WE NEED TO FIX NOW!"); } } + info!("JavaPlatform asked app to send SignalingEvent"); } Event::CallState(_peer_id, call_id, CallState::Incoming(call_media_type)) => { info!("[JV] CALLSTATEEVEMNT"); let direction = 0; unsafe { - (self.statusCallback)(call_id, 1, direction, call_media_type as i32); + (self.statusCallback)(call_id.as_u64(), 1, direction, call_media_type as i32); } } Event::CallState(_peer_id, call_id, CallState::Outgoing(call_media_type)) => { info!("[JV] CALLSTATEEVEMNT"); let direction = 1; unsafe { - (self.statusCallback)(call_id, 1, direction, call_media_type as i32); + (self.statusCallback)(call_id.as_u64(), 1, direction, call_media_type as i32); } } Event::CallState(_peer_id, call_id, state) => { @@ -199,9 +205,20 @@ impl EventReporter { }; info!("New state = {} and index = {}", state_string, state_index); unsafe { - (self.statusCallback)(call_id, 1, 10 * state_index, 0); + (self.statusCallback)(call_id.as_u64(), 1, 10 * state_index, 0); } } + Event::RemoteVideoStateChange(peer_id, enabled) => { + info!("RemoveVideoStateChange to {}", enabled); + unsafe { + if enabled { + (self.statusCallback)(1, 1, 22, 31); + } else { + (self.statusCallback)(1, 1, 22, 32); + } + } + } + _ => { info!("[JV] unknownevent"); } @@ -351,15 +368,17 @@ pub struct CallEndpoint { // Boxed so we can pass it as a Box incoming_video_sink: Box, peer_connection_factory: PeerConnectionFactory, + videoFrameCallback: extern "C" fn(*const u8, u32, u32, size_t), } impl CallEndpoint { fn new<'a>( use_new_audio_device_module: bool, - statusCallback: extern "C" fn(CallId, u64, i32, i32), + statusCallback: extern "C" fn(u64, u64, i32, i32), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), + videoFrameCallback: extern "C" fn(*const u8, u32, u32, size_t), ) -> Result { // Relevant for both group calls and 1:1 calls let (events_sender, _events_receiver) = channel::(); @@ -415,6 +434,7 @@ impl CallEndpoint { outgoing_video_track, incoming_video_sink, peer_connection_factory, + videoFrameCallback, }) } } @@ -426,6 +446,11 @@ struct LastFramesVideoSink { impl VideoSink for LastFramesVideoSink { fn on_video_frame(&self, track_id: u32, frame: VideoFrame) { +info!("Got videoframe!"); +// let myframe: &mut[u8;512] = &mut [0;512]; +// frame.to_rgba(myframe.as_mut_slice()); +// info!("uploading frame = {:?}", myframe); +// info!("frame uploaded"); self.last_frame_by_track_id .lock() .unwrap() @@ -469,10 +494,11 @@ pub unsafe extern "C" fn getVersion() -> i64 { #[no_mangle] pub unsafe extern "C" fn createCallEndpoint( - statusCallback: extern "C" fn(CallId, u64, i32, i32), + statusCallback: extern "C" fn(u64, u64, i32, i32), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), + videoFrameCallback: extern "C" fn(*const u8, u32, u32, size_t), ) -> i64 { let call_endpoint = CallEndpoint::new( false, @@ -480,6 +506,7 @@ pub unsafe extern "C" fn createCallEndpoint( answerCallback, offerCallback, iceUpdateCallback, + videoFrameCallback, ) .unwrap(); let call_endpoint_box = Box::new(call_endpoint); @@ -643,9 +670,8 @@ pub unsafe extern "C" fn receivedIce( sender_device_id: DeviceId, icepack: JByteArray2D, ) { - info!("JavaRing, received_ice with length = {}", icepack.len); + info!("receivedIce from app with length = {}", icepack.len); let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); - info!("Received offer, endpoint = {:?}", endpoint); let call_id = CallId::from(call_id); let mut ice_candidates = Vec::new(); for j in 0..icepack.len { @@ -662,12 +688,13 @@ pub unsafe extern "C" fn receivedIce( sender_device_id, }, ); + info!("receivedIce invoked call_manager and will now return to app"); } #[no_mangle] pub unsafe extern "C" fn acceptCall(endpoint: i64, call_id: u64) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); - info!("now accept call"); + info!("acceptCall requested by app"); let call_id = CallId::from(call_id); endpoint.call_manager.accept_call(call_id); 573 @@ -725,3 +752,56 @@ pub unsafe extern "C" fn setOutgoingAudioEnabled(endpoint: i64, enable: bool) -> endpoint.outgoing_audio_track.set_enabled(enable); 1 } + + +#[no_mangle] +pub unsafe extern "C" fn setOutgoingVideoEnabled(endpoint: i64, enable: bool) -> i64 { + info!("Hava to setOutgoingVideoEnabled({})", enable); + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + endpoint.outgoing_video_track.set_enabled(enable); + let mut active_connection = endpoint.call_manager.active_connection(); + active_connection.expect("No active connection!").update_sender_status(signaling::SenderStatus { + video_enabled: Some(enable), + ..Default::default() + }); + 1 +} + +#[no_mangle] +pub unsafe extern "C" fn sendVideoFrame(endpoint: i64, width: u32, height: u32, pixel_format: i32, raw: *const u8) -> i64 { + info!("Will send VideoFrame"); + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + let size = width * height * 4; + let buffer: &[u8] = unsafe {slice::from_raw_parts(raw, size as usize)}; + + let pixel_format = VideoPixelFormat::from_i32(pixel_format); + let pixel_format = pixel_format.unwrap(); + info!("buf[0] = {} and buf[1] = {} and buf[300] = {}, size = {}", buffer[0], buffer[1], buffer[300], size); + let frame = VideoFrame::copy_from_slice(width, height, pixel_format, buffer); + endpoint.outgoing_video_source.push_frame(frame); + 1 +} + + + +#[no_mangle] +pub unsafe extern "C" fn retrieveRemoteVideoFrame(endpoint: i64) -> i64 { + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("Have to retrieve remote video frame"); + let frame = endpoint.incoming_video_sink.pop(0); + if let Some(frame) = frame { + let frame = frame.apply_rotation(); + let width: u32 = frame.width(); + let height: u32 = frame.height(); + let myframe: &mut[u8] = &mut [0;512000]; + frame.to_rgba(myframe); + info!("Frame0 = {}, w = {}, h = {}", myframe[0], frame.width(), frame.height()); + let o1 = Box::new(myframe); + let op = o1.as_ptr(); + (endpoint.videoFrameCallback)(op, width, height, 512000); + 1 + } else { + 0 + } +} + diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index 9e55ebf2..2903d3f5 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -1,3 +1,5 @@ +#![allow(unused_parens)] + use crate::core::signaling; use core::slice; use std::fmt; @@ -154,3 +156,9 @@ impl JByteArray2D { } } } + +#[repr(C)] +struct Buffer { + data: *mut u8, + len: usize, +} From 0ac7b805168a22b2d9c3497be5a5f9f43c76dcf4 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 5 Dec 2022 11:49:05 +0100 Subject: [PATCH 51/74] enable incoming and outgoing video. This has lots of debug info which we will remove in the next version --- .../java/io/privacyresearch/tring/TringServiceImpl.java | 6 +++--- .../main/java/io/privacyresearch/tringapi/TringBridge.java | 6 +++--- .../main/java/io/privacyresearch/tringapi/TringService.java | 2 +- src/rust/src/java/java.rs | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 5450190c..e7e4a92a 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -139,11 +139,11 @@ public void hangupCall() { * @return the same call_id as the one we were passed, if success */ @Override - public long startOutgoingCall(long callId, String peerId, int localDeviceId) { - LOG.info("Tring will start outgoing call to "+peerId+" with localDevice "+localDeviceId); + public long startOutgoingCall(long callId, String peerId, int localDeviceId, boolean enableVideo) { + LOG.info("Tring will start outgoing call to "+peerId+" with localDevice "+localDeviceId+" and enableVideo = "+enableVideo); tringlib_h.setAudioInput(callEndpoint, (short)0); tringlib_h.setAudioOutput(callEndpoint, (short)0); - tringlib_h.createOutgoingCall(callEndpoint, toJString(scope, peerId), false, localDeviceId, callId); + tringlib_h.createOutgoingCall(callEndpoint, toJString(scope, peerId), enableVideo, localDeviceId, callId); return callId; } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index bbccbd2d..0969640b 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -71,8 +71,8 @@ public void receivedAnswer(String peerId, long callId, int receiverDeviceId, service.receivedAnswer(peerId, callId, receiverDeviceId, senderKey, receiverKey, opaque); } - public long startOutgoingCall(long callId, String peerId, int localDeviceId) { - return service.startOutgoingCall(callId, peerId, localDeviceId); + public long startOutgoingCall(long callId, String peerId, int localDeviceId, boolean enableVideo) { + return service.startOutgoingCall(callId, peerId, localDeviceId, enableVideo); } public void enableOutgoingVideo(boolean enable) { @@ -84,7 +84,7 @@ public byte[] getRemoteVideoFrame() { } public void sendVideoFrame(int width, int height, byte[] raw) { - service.sendVideoFrame(width, width, raw); + service.sendVideoFrame(width, height, raw); } } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index 1d850170..944b4466 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -27,7 +27,7 @@ public void receivedOffer(String peerId, long callId, int senderDeviceId, int re public void receivedAnswer(String peerId, long callId, int senderDeviceId, byte[] senderKey, byte[] receiverKey, byte[] opaque); - public long startOutgoingCall(long callId, String peerId, int localDeviceId); + public long startOutgoingCall(long callId, String peerId, int localDeviceId, boolean enableVideo); public default String getVersionInfo() { return "Unresolved TringService"; diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index a89e3311..a6d2f0c3 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -769,9 +769,9 @@ pub unsafe extern "C" fn setOutgoingVideoEnabled(endpoint: i64, enable: bool) -> #[no_mangle] pub unsafe extern "C" fn sendVideoFrame(endpoint: i64, width: u32, height: u32, pixel_format: i32, raw: *const u8) -> i64 { - info!("Will send VideoFrame"); let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let size = width * height * 4; + info!("Will send VideoFrame, width = {}, heigth = {}, pixelformat = {}, size = {}",width, height, pixel_format, size); let buffer: &[u8] = unsafe {slice::from_raw_parts(raw, size as usize)}; let pixel_format = VideoPixelFormat::from_i32(pixel_format); From 59d736e4b63222928b215cebfb04ea21a5e18762 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 5 Dec 2022 11:58:21 +0100 Subject: [PATCH 52/74] Fix rust fmt --- src/rust/src/core/connection.rs | 2 +- src/rust/src/java/java.rs | 62 ++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/rust/src/core/connection.rs b/src/rust/src/core/connection.rs index 2e4c4511..e4ea9c2d 100644 --- a/src/rust/src/core/connection.rs +++ b/src/rust/src/core/connection.rs @@ -2061,7 +2061,7 @@ where _video_frame_metadata: VideoFrameMetadata, video_frame: Option, ) -> Result<()> { -info!("Hello, incoming video frame"); + info!("Hello, incoming video frame"); if let (Some(incoming_video_sink), Some(video_frame)) = (self.incoming_video_sink.as_ref(), video_frame) { diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index a6d2f0c3..8a23cc45 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -27,7 +27,9 @@ use crate::native::{ NativePlatform, PeerId, SignalingSender, }; use crate::webrtc::logging; -use crate::webrtc::media::{AudioTrack, VideoFrame, VideoPixelFormat, VideoSink, VideoSource, VideoTrack}; +use crate::webrtc::media::{ + AudioTrack, VideoFrame, VideoPixelFormat, VideoSink, VideoSource, VideoTrack, +}; use crate::webrtc::peer_connection::AudioLevel; @@ -135,7 +137,10 @@ impl EventReporter { info!("JavaPlatform needs to send SignalingEvent to app"); match signal { signaling::Message::Offer(offer) => { - info!("[JV] SendSignaling OFFER Event and call_id = {}", call_id.as_u64()); + info!( + "[JV] SendSignaling OFFER Event and call_id = {}", + call_id.as_u64() + ); let op = JArrayByte::new(offer.opaque); unsafe { (self.offerCallback)(op); @@ -446,11 +451,11 @@ struct LastFramesVideoSink { impl VideoSink for LastFramesVideoSink { fn on_video_frame(&self, track_id: u32, frame: VideoFrame) { -info!("Got videoframe!"); -// let myframe: &mut[u8;512] = &mut [0;512]; -// frame.to_rgba(myframe.as_mut_slice()); -// info!("uploading frame = {:?}", myframe); -// info!("frame uploaded"); + info!("Got videoframe!"); + // let myframe: &mut[u8;512] = &mut [0;512]; + // frame.to_rgba(myframe.as_mut_slice()); + // info!("uploading frame = {:?}", myframe); + // info!("frame uploaded"); self.last_frame_by_track_id .lock() .unwrap() @@ -753,37 +758,48 @@ pub unsafe extern "C" fn setOutgoingAudioEnabled(endpoint: i64, enable: bool) -> 1 } - #[no_mangle] pub unsafe extern "C" fn setOutgoingVideoEnabled(endpoint: i64, enable: bool) -> i64 { info!("Hava to setOutgoingVideoEnabled({})", enable); let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); endpoint.outgoing_video_track.set_enabled(enable); let mut active_connection = endpoint.call_manager.active_connection(); - active_connection.expect("No active connection!").update_sender_status(signaling::SenderStatus { - video_enabled: Some(enable), - ..Default::default() - }); + active_connection + .expect("No active connection!") + .update_sender_status(signaling::SenderStatus { + video_enabled: Some(enable), + ..Default::default() + }); 1 } #[no_mangle] -pub unsafe extern "C" fn sendVideoFrame(endpoint: i64, width: u32, height: u32, pixel_format: i32, raw: *const u8) -> i64 { +pub unsafe extern "C" fn sendVideoFrame( + endpoint: i64, + width: u32, + height: u32, + pixel_format: i32, + raw: *const u8, +) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let size = width * height * 4; - info!("Will send VideoFrame, width = {}, heigth = {}, pixelformat = {}, size = {}",width, height, pixel_format, size); - let buffer: &[u8] = unsafe {slice::from_raw_parts(raw, size as usize)}; + info!( + "Will send VideoFrame, width = {}, heigth = {}, pixelformat = {}, size = {}", + width, height, pixel_format, size + ); + let buffer: &[u8] = unsafe { slice::from_raw_parts(raw, size as usize) }; let pixel_format = VideoPixelFormat::from_i32(pixel_format); let pixel_format = pixel_format.unwrap(); - info!("buf[0] = {} and buf[1] = {} and buf[300] = {}, size = {}", buffer[0], buffer[1], buffer[300], size); + info!( + "buf[0] = {} and buf[1] = {} and buf[300] = {}, size = {}", + buffer[0], buffer[1], buffer[300], size + ); let frame = VideoFrame::copy_from_slice(width, height, pixel_format, buffer); endpoint.outgoing_video_source.push_frame(frame); 1 } - - #[no_mangle] pub unsafe extern "C" fn retrieveRemoteVideoFrame(endpoint: i64) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); @@ -793,9 +809,14 @@ pub unsafe extern "C" fn retrieveRemoteVideoFrame(endpoint: i64) -> i64 { let frame = frame.apply_rotation(); let width: u32 = frame.width(); let height: u32 = frame.height(); - let myframe: &mut[u8] = &mut [0;512000]; + let myframe: &mut [u8] = &mut [0; 512000]; frame.to_rgba(myframe); - info!("Frame0 = {}, w = {}, h = {}", myframe[0], frame.width(), frame.height()); + info!( + "Frame0 = {}, w = {}, h = {}", + myframe[0], + frame.width(), + frame.height() + ); let o1 = Box::new(myframe); let op = o1.as_ptr(); (endpoint.videoFrameCallback)(op, width, height, 512000); @@ -804,4 +825,3 @@ pub unsafe extern "C" fn retrieveRemoteVideoFrame(endpoint: i64) -> i64 { 0 } } - From c56c7deea3e4585853bc4cfc78b0a6fb9e4d822b Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 5 Dec 2022 12:02:30 +0100 Subject: [PATCH 53/74] remove debug info --- .../main/java/io/privacyresearch/tring/TringServiceImpl.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index e7e4a92a..1b7393d7 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -327,14 +327,11 @@ Addressable createVideoFrameCallback() { class VideoFrameCallbackImpl implements createCallEndpoint$videoFrameCallback { @Override public void apply(MemoryAddress opaque, int w, int h, long size) { - System.err.println("TRINGBRIDGE, send video data!"); - System.err.println("TRING, videobytessize = "+size); + LOG.fine("Got incoming video frame in Java layer"); MemorySegment segment = MemorySegment.ofAddress(opaque, size, scope); - System.err.println("got segment = "+ segment); byte[] raw = segment.toArray(ValueLayout.JAVA_BYTE); api.getVideoFrame(w, h, raw); sendAck(); - System.err.println("TRING, ack sent for videoframe"); } } From 339b140b0cc90e82a7c6b68118ad2447a642a613 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 5 Dec 2022 12:16:31 +0100 Subject: [PATCH 54/74] Build tring api 0.0.5 tring 0.0.8 --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index beb10139..94961a9d 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.8-SNAPSHOT + 0.0.8 jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.5-SNAPSHOT + 0.0.5 diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index faf5c496..23c83ffb 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.5-SNAPSHOT + 0.0.5 jar UTF-8 From f64a7d119952f7aef47d9a6efc75b607970d63fd Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Tue, 6 Dec 2022 20:10:48 +0100 Subject: [PATCH 55/74] Allow to pass pixelformat when uploading a frame to outgoingVideo --- .../main/java/io/privacyresearch/tring/TringServiceImpl.java | 4 ++-- .../main/java/io/privacyresearch/tringapi/TringBridge.java | 4 ++-- .../main/java/io/privacyresearch/tringapi/TringService.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 1b7393d7..a4dc0b12 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -159,9 +159,9 @@ public void enableOutgoingVideo(boolean enable) { } @Override - public void sendVideoFrame(int w, int h, byte[] raw) { + public void sendVideoFrame(int w, int h, int pixelFormat, byte[] raw) { MemorySegment buff = scope.allocateArray(ValueLayout.JAVA_BYTE, raw); - tringlib_h.sendVideoFrame(callEndpoint, w, h, 1, buff); + tringlib_h.sendVideoFrame(callEndpoint, w, h, pixelFormat, buff); } static MemorySegment toJByteArray2D(MemorySession ms, List rows) { diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index 0969640b..54768fd3 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -83,8 +83,8 @@ public byte[] getRemoteVideoFrame() { return service.getRemoteVideoFrame(); } - public void sendVideoFrame(int width, int height, byte[] raw) { - service.sendVideoFrame(width, height, raw); + public void sendVideoFrame(int width, int height, int pixelFormat, byte[] raw) { + service.sendVideoFrame(width, height, pixelFormat, raw); } } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index 944b4466..409b9af7 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -40,6 +40,6 @@ public default String getVersionInfo() { public void enableOutgoingVideo(boolean enable); public byte[] getRemoteVideoFrame(); - public void sendVideoFrame(int w, int h, byte[] raw); + public void sendVideoFrame(int w, int h, int pixelFormat, byte[] raw); } From 3658da861e2746d04c4b13157aed3449a4f313a3 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Wed, 7 Dec 2022 14:14:33 +0100 Subject: [PATCH 56/74] Increase versions to snapshot versions --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 94961a9d..b02d9fd2 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.8 + 0.0.9-SNAPSHOT jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.5 + 0.0.6-SNAPSHOT diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index 23c83ffb..b7f5b543 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.5 + 0.0.6-SNAPSHOT jar UTF-8 From 2d711af508156cf467fb6915c1df10600b004262 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Wed, 7 Dec 2022 14:17:40 +0100 Subject: [PATCH 57/74] New session for video upload --- .../java/io/privacyresearch/tring/TringServiceImpl.java | 6 ++++-- src/rust/src/java/java.rs | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index a4dc0b12..9ce805ba 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -160,8 +160,10 @@ public void enableOutgoingVideo(boolean enable) { @Override public void sendVideoFrame(int w, int h, int pixelFormat, byte[] raw) { - MemorySegment buff = scope.allocateArray(ValueLayout.JAVA_BYTE, raw); - tringlib_h.sendVideoFrame(callEndpoint, w, h, pixelFormat, buff); + try ( MemorySession session = MemorySession.openConfined()) { + MemorySegment buff = session.allocateArray(ValueLayout.JAVA_BYTE, raw); + tringlib_h.sendVideoFrame(callEndpoint, w, h, pixelFormat, buff); + } } static MemorySegment toJByteArray2D(MemorySession ms, List rows) { diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 8a23cc45..224c8b02 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -782,7 +782,10 @@ pub unsafe extern "C" fn sendVideoFrame( raw: *const u8, ) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); - let size = width * height * 4; + let mut size = width * height * 2; + if (pixel_format == 1) { + size = size * 2; + } info!( "Will send VideoFrame, width = {}, heigth = {}, pixelformat = {}, size = {}", width, height, pixel_format, size From c41134abac6dd3d8b7541e04690233ae1359fe50 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 8 Dec 2022 14:32:00 +0100 Subject: [PATCH 58/74] Asynchonous remote video retrieval --- .../tring/TringServiceImpl.java | 48 ++++++++++++++++--- .../io/privacyresearch/tringapi/TringApi.java | 2 +- .../privacyresearch/tringapi/TringBridge.java | 2 +- .../tringapi/TringService.java | 11 ++++- src/rust/src/java/java.rs | 16 ++++--- 5 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 9ce805ba..423396b4 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -1,6 +1,6 @@ package io.privacyresearch.tring; -import io.privacyresearch.tringapi.TringApi; +import io.privacyresearch.tringapi.TringFrame; import io.privacyresearch.tringapi.TringService; import java.lang.foreign.Addressable; import java.lang.foreign.MemoryAddress; @@ -9,7 +9,9 @@ import java.lang.foreign.ValueLayout; import java.util.ArrayList; import java.util.List; -import java.util.Random; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.logging.Level; import java.util.logging.Logger; public class TringServiceImpl implements TringService { @@ -23,7 +25,8 @@ public class TringServiceImpl implements TringService { private io.privacyresearch.tringapi.TringApi api; private long activeCallId; static String libName = "unknown"; - + BlockingQueue frameQueue = new LinkedBlockingQueue(); + private static final Logger LOG = Logger.getLogger(TringServiceImpl.class.getName()); static { @@ -148,8 +151,34 @@ public long startOutgoingCall(long callId, String peerId, int localDeviceId, boo } @Override - public byte[] getRemoteVideoFrame() { - long a= tringlib_h.retrieveRemoteVideoFrame(callEndpoint); + public TringFrame getRemoteVideoFrame(boolean skip) { + LOG.info("Get remote videoframe"); + try { + long a = tringlib_h.retrieveRemoteVideoFrame(callEndpoint); + int i = 0; + while (a == 0) { + Thread.sleep(50); + a = tringlib_h.retrieveRemoteVideoFrame(callEndpoint); + i++; + if (i > 40) return null; + } + LOG.info("Asked for a remote frame"); + synchronized (frameQueue) { + TringFrame frame = frameQueue.poll(); + if (frame == null) { + frameQueue.wait(15000); + frame = frameQueue.poll(); + } + LOG.info("Got a remote frame? " + frame); + if (frame != null) { + return frame; + } + } + + } catch (InterruptedException ex) { + LOG.log(Level.SEVERE, null, ex); + } + LOG.info("Didn't receive a video frame from the other side in 15 seconds, return null"); return null; } @@ -329,10 +358,15 @@ Addressable createVideoFrameCallback() { class VideoFrameCallbackImpl implements createCallEndpoint$videoFrameCallback { @Override public void apply(MemoryAddress opaque, int w, int h, long size) { - LOG.fine("Got incoming video frame in Java layer"); + LOG.info("Got incoming video frame in Java layer"); MemorySegment segment = MemorySegment.ofAddress(opaque, size, scope); byte[] raw = segment.toArray(ValueLayout.JAVA_BYTE); - api.getVideoFrame(w, h, raw); + synchronized (frameQueue) { + LOG.info("Add frame to queue"); + frameQueue.add(new TringFrame(w,h,-1,raw)); + frameQueue.notifyAll(); + } + LOG.info("Processed incoming video frame in Java layer"); sendAck(); } } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java index 49b6b4c3..1497dfd8 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java @@ -16,6 +16,6 @@ public interface TringApi { void iceUpdateCallback(List iceCandidates); - void getVideoFrame(int w, int h, byte[] raw); + // void getVideoFrame(int w, int h, byte[] raw); } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index 54768fd3..3f113092 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -79,7 +79,7 @@ public void enableOutgoingVideo(boolean enable) { service.enableOutgoingVideo(enable); } - public byte[] getRemoteVideoFrame() { + public TringFrame getRemoteVideoFrame() { return service.getRemoteVideoFrame(); } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index 409b9af7..b9de79e3 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -39,7 +39,16 @@ public default String getVersionInfo() { */ public void enableOutgoingVideo(boolean enable); - public byte[] getRemoteVideoFrame(); + /** + * Get a videoframe from the other side. + * @param skip if true, ignore all old frames, and return the most recent one + * @return a frame + */ + public TringFrame getRemoteVideoFrame(boolean skip); + + public default TringFrame getRemoteVideoFrame() { + return getRemoteVideoFrame(false); + } public void sendVideoFrame(int w, int h, int pixelFormat, byte[] raw); } diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 224c8b02..fcdb37da 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -764,12 +764,16 @@ pub unsafe extern "C" fn setOutgoingVideoEnabled(endpoint: i64, enable: bool) -> let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); endpoint.outgoing_video_track.set_enabled(enable); let mut active_connection = endpoint.call_manager.active_connection(); - active_connection - .expect("No active connection!") - .update_sender_status(signaling::SenderStatus { - video_enabled: Some(enable), - ..Default::default() - }); + if (active_connection.is_ok()) { + active_connection + .expect("No active connection!") + .update_sender_status(signaling::SenderStatus { + video_enabled: Some(enable), + ..Default::default() + }); + } else { + info!("No active connection") + } 1 } From 4d632da3c178e155a52a56e228d97e55cc1d15ab Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 8 Dec 2022 14:40:16 +0100 Subject: [PATCH 59/74] Build tring 0.0.9 and api 0.0.6 --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index b02d9fd2..7231f928 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.9-SNAPSHOT + 0.0.9 jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.6-SNAPSHOT + 0.0.6 diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index b7f5b543..23120360 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.6-SNAPSHOT + 0.0.6 jar UTF-8 From d8075409b98863b42123b3df2d4371ceffa8de1d Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 8 Dec 2022 14:49:30 +0100 Subject: [PATCH 60/74] Add missing class --- .../io/privacyresearch/tringapi/TringFrame.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringFrame.java diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringFrame.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringFrame.java new file mode 100644 index 00000000..de4e352d --- /dev/null +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringFrame.java @@ -0,0 +1,14 @@ +package io.privacyresearch.tringapi; + +public class TringFrame { + + public final int width, height, pixelFormat; + public final byte[] data; + + public TringFrame(int width, int height, int pixelFormat, byte[] data) { + this.width = width; + this.height = height; + this.pixelFormat = pixelFormat; + this.data = data; + } +} From 1e7a464c6a629ef11144a0671922cf1ee4fd927c Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 8 Dec 2022 22:54:02 +0100 Subject: [PATCH 61/74] prepare new snapshots --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 7231f928..3b427078 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.9 + 0.0.10-SNAPSHOT jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.6 + 0.0.7-SNAPSHOT diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index 23120360..2d49a95d 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.6 + 0.0.7-SNAPSHOT jar UTF-8 From 929986e98b96988c3287e4b14877c55f0b624d86 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 8 Dec 2022 22:59:32 +0100 Subject: [PATCH 62/74] add real deviceId of accepting device instead of dummy `1` Fix for https://github.com/privacyresearchgroup/wave-app/issues/992 --- bin/build-java | 1 + src/rust/src/java/java.rs | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/build-java b/bin/build-java index 4789cef7..989f40a9 100755 --- a/bin/build-java +++ b/bin/build-java @@ -158,5 +158,6 @@ export MACOSX_DEPLOYMENT_TARGET="10.10" cd ../java/tringapi mvn clean install cd ../tring + echo "mvn -Dclassifier=$DEFAULT_PLATFORM-$CARGO_ARCH clean install" mvn -Dclassifier=$DEFAULT_PLATFORM-$CARGO_ARCH clean install ) diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index fcdb37da..052e48a4 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -170,8 +170,7 @@ impl EventReporter { unsafe { (self.statusCallback)( call_id.as_u64(), - 1, - // hangup_device_id.unwrap().into(), + hangup_device_id.unwrap().into(), 11, hangup_type as i32, ); From 7251e64741db731dd2a8c4218a5d268a4a98e890 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 9 Dec 2022 11:24:43 +0100 Subject: [PATCH 63/74] Whenever Tring processes a (signaling/status) event that is received as a message, we need to send an ack back to ringrtc so that it continues sending us events. In case there is no deviceId (anymore) on the call object, just send 0 in hangup --- .../java/io/privacyresearch/tring/TringServiceImpl.java | 5 ++++- src/rust/src/java/java.rs | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 423396b4..21cfd5ed 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -288,8 +288,9 @@ Addressable createStatusCallback() { class StatusCallbackImpl implements createCallEndpoint$statusCallback { @Override public void apply(long id, long _x1, int direction, int type) { - // long id = CallId.id$get(callId); + LOG.info("Got new status from ringrtc, id = " + id+", x1 = " + _x1+", dir = " + direction+", type = "+type); api.statusCallback(id, _x1, direction, type); + sendAck(); } } @@ -371,6 +372,8 @@ public void apply(MemoryAddress opaque, int w, int h, long size) { } } + // We need to inform ringrtc that we handled a message, so that it is ok + // with sending the next message void sendAck() { MemorySegment callid = MemorySegment.allocateNative(8, scope); callid.set(ValueLayout.JAVA_LONG, 0l, activeCallId); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 052e48a4..476d1748 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -166,11 +166,15 @@ impl EventReporter { } signaling::Message::Hangup(hangup) => { let (hangup_type, hangup_device_id) = hangup.to_type_and_device_id(); + let device_id: u64 = match hangup_device_id { + Some(device_id) => device_id.into(), + None => 0, + }; info!("[JV] SendSignaling Hangup Event"); unsafe { (self.statusCallback)( call_id.as_u64(), - hangup_device_id.unwrap().into(), + device_id, 11, hangup_type as i32, ); From def746ee3f572781abc2febd39fea37d8e9cfd98 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 11 Dec 2022 21:21:12 +0100 Subject: [PATCH 64/74] Release tringapi 0.0.7 and tring 0.0.10 --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 3b427078..14115e49 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.10-SNAPSHOT + 0.0.10 jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.7-SNAPSHOT + 0.0.7 diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index 2d49a95d..30240c21 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.7-SNAPSHOT + 0.0.7 jar UTF-8 From a01c1029e6f156184f9b19a912494a35880b7af0 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Thu, 15 Dec 2022 11:40:15 +0100 Subject: [PATCH 65/74] Prepare next snapshots --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index 14115e49..a181f867 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.10 + 0.0.11-SNAPSHOT jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.7 + 0.0.8-SNAPSHOT diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index 30240c21..758701a3 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.7 + 0.0.8-SNAPSHOT jar UTF-8 From df29a391240cc47d2183d63b6bc1da8a25b38232 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 9 Dec 2022 22:04:31 +0100 Subject: [PATCH 66/74] get audio inputs --- .../tring/TringServiceImpl.java | 1 + src/rust/build.rs | 2 +- src/rust/src/java/java.rs | 38 ++++++++- src/rust/src/java/jtypes.rs | 83 +++++++++++++++++++ 4 files changed, 121 insertions(+), 3 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 21cfd5ed..7d7da96f 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -104,6 +104,7 @@ public void setSelfUuid(String uuid) { @Override public void proceed(long callId, String iceUser, String icePwd, List ice) { MemorySegment icePack = toJByteArray2D(scope, ice); + tringlib_h.setOutgoingAudioEnabled(callEndpoint, true); tringlib_h.proceedCall(callEndpoint, callId, 0, 0, toJString(scope, iceUser), toJString(scope, icePwd), icePack); } diff --git a/src/rust/build.rs b/src/rust/build.rs index 58299457..676bb01b 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("uuunable to generate bindings") + .expect("uunable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 476d1748..7bd131df 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -18,7 +18,7 @@ use crate::core::group_call::{GroupId, SignalingMessageUrgency}; use crate::core::signaling; use crate::core::util::ptr_as_mut; -use crate::java::jtypes::{JArrayByte, JArrayByte2D, JByteArray, JByteArray2D, JString}; +use crate::java::jtypes::{JArrayByte, JArrayByte2D, JByteArray, JByteArray2D, JString, TringDevice}; use crate::lite::http; use crate::lite::sfu::UserId; @@ -33,7 +33,7 @@ use crate::webrtc::media::{ use crate::webrtc::peer_connection::AudioLevel; -use crate::webrtc::peer_connection_factory::{self as pcf, IceServer, PeerConnectionFactory}; +use crate::webrtc::peer_connection_factory::{self as pcf, AudioDevice, IceServer, PeerConnectionFactory}; use crate::webrtc::peer_connection_observer::NetworkRoute; fn init_logging() { @@ -733,8 +733,29 @@ pub unsafe extern "C" fn signalMessageSent(endpoint: i64, call_id: CallId) -> i6 135 } +#[no_mangle] +#[allow(non_snake_case)] +pub unsafe extern "C" fn getAudioInputs(idx: u32, endpoint: i64) -> TringDevice<'static> { + let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + let devices = callendpoint + .peer_connection_factory + .get_audio_recording_devices().unwrap(); + // let mut answer: [TringDevice;16] = [TringDevice::empty();16]; + let mut answer: TringDevice = TringDevice::empty(); + for (i, device) in devices.iter().enumerate() { + let wd = TringDevice::from_fields(i as u32, device.name.clone(), device.unique_id.clone(), device.i18n_key.clone()); + if (i as u32 == idx) { + answer = wd; + } + // answer[i] = wd; + } + answer +} + #[no_mangle] pub unsafe extern "C" fn setAudioInput(endpoint: i64, index: u16) -> i64 { +// getAudioInputs(endpoint); +// getAudioOutputs(endpoint); let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); info!("Have to set audio_recordig_device to {}", index); endpoint @@ -743,6 +764,19 @@ pub unsafe extern "C" fn setAudioInput(endpoint: i64, index: u16) -> i64 { 1 } +#[no_mangle] +pub unsafe extern "C" fn getAudioOutputs(endpoint: i64) -> i64 { + let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + let devices = callendpoint + .peer_connection_factory + .get_audio_playout_devices(); + + for device in devices.iter() { + info!("OUTDEVICE = {:#?}", device); + } +1 +} + #[no_mangle] pub unsafe extern "C" fn setAudioOutput(endpoint: i64, index: u16) -> i64 { let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index 2903d3f5..5316b1e2 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -1,6 +1,8 @@ #![allow(unused_parens)] use crate::core::signaling; +use crate::webrtc::peer_connection_factory::AudioDevice; + use core::slice; use std::fmt; @@ -16,7 +18,41 @@ impl JString { let answer = unsafe { String::from_raw_parts(self.buff, self.len, self.len) }; answer } + +/* + pub fn from_string(src: String) -> Self { + let string_len = src.len(); + let mut string_bytes = src.as_bytes().as_mut_ptr(); + Self { + len: string_len, + buff: string_bytes + } + } +*/ +} + +#[repr(C)] +#[derive(Clone, Copy, Debug)] +pub struct RString<'a> { + len: usize, + buff: *const u8, + phantom: std::marker::PhantomData<&'a u8>, +} + +impl<'a> RString<'a> { + + pub fn from_string(src: String) -> Self { + let string_len = src.len(); + let mut string_bytes = src.as_bytes().as_ptr(); + Self { + len: string_len, + buff: string_bytes, + phantom: std::marker::PhantomData, + } + } } + + #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct JArrayByte { @@ -162,3 +198,50 @@ struct Buffer { data: *mut u8, len: usize, } + +#[repr(C)] +#[derive(Clone, Copy, Debug)] +pub struct TringDevice<'a> { + index: u32, + name: RString<'a>, + unique_id: RString<'a>, + int_key: RString<'a>, +} + +impl<'a> TringDevice<'a> { + pub fn empty() -> Self { + let name = RString::from_string("empty".to_string()); + let unique_id = RString::from_string("empty".to_string()); + let int_key = RString::from_string("empty".to_string()); + Self { + index: 99, + name: name, + unique_id: unique_id, + int_key: int_key + } + } + + pub fn from_audio_device(index: u32, src: AudioDevice) -> Self { + let src_name = RString::from_string(src.name); + let src_unique_id = RString::from_string(src.unique_id); + let src_int_key = RString::from_string(src.i18n_key); + Self { + index: index, + name: src_name, + unique_id: src_unique_id, + int_key: src_int_key, + } + } + pub fn from_fields(index: u32, src_name:String, src_unique_id:String, src_i18n_key:String) -> Self { + let src_name = RString::from_string(src_name); + let src_unique_id = RString::from_string(src_unique_id); + let src_int_key = RString::from_string(src_i18n_key); + Self { + index: index, + name: src_name, + unique_id: src_unique_id, + int_key: src_int_key, + } + } +} + From 4c3d4631e669ebb5527758e841eb346ec460cb04 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 11 Dec 2022 15:07:00 +0100 Subject: [PATCH 67/74] make sure it doesn't impact normal flow --- .../tring/TringServiceImpl.java | 26 +++++++++++++++++++ src/rust/src/java/java.rs | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 7d7da96f..937e89b0 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -7,6 +7,7 @@ import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.BlockingQueue; @@ -70,6 +71,31 @@ private void initiate() { this.callEndpoint = tringlib_h.createCallEndpoint(createStatusCallback(), createAnswerCallback(), createOfferCallback(), createIceUpdateCallback(), createVideoFrameCallback()); + + } + + private void processAudioInputs() { + System.err.println("GOT CE"); + MemorySegment audioInputs = tringlib_h.getAudioInputs(scope, callEndpoint,0); + System.err.println("GOT AI"); + MemorySegment name = TringDevice.name$slice(audioInputs); + System.err.println("GOT NAME"); + int namelen = (int)RString.len$get(name); + System.err.println("LEN = "+namelen); + MemoryAddress namebuff = RString.buff$get(name); + MemorySegment ofAddress = MemorySegment.ofAddress(namebuff, namelen, scope); + ByteBuffer bb = ofAddress.asByteBuffer(); + byte[] bname = new byte[namelen]; + bb.get(bname, 0, (int)namelen); + // byte[] bname = bb.array(); + // byte[] bname = ofAddress.toArray(ValueLayout.JAVA_BYTE); +// byte[] bname = new byte[(int)namelen]; +// for (int i = 0; i < namelen; i++) { +// bname[i] = namebuff.get(ValueLayout.JAVA_BYTE, i); +// } + System.err.println("NAME = "+java.util.Arrays.toString(bname)); + String myname = new String(bname); + System.err.println("hence, myname = "+myname); } @Override diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 7bd131df..08022894 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -735,7 +735,7 @@ pub unsafe extern "C" fn signalMessageSent(endpoint: i64, call_id: CallId) -> i6 #[no_mangle] #[allow(non_snake_case)] -pub unsafe extern "C" fn getAudioInputs(idx: u32, endpoint: i64) -> TringDevice<'static> { +pub unsafe extern "C" fn getAudioInputs(endpoint: i64, idx: u32) -> TringDevice<'static> { let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let devices = callendpoint .peer_connection_factory From ece2404330444fe6439f4356c448a85d04072706 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Sun, 11 Dec 2022 20:04:46 +0100 Subject: [PATCH 68/74] remove debug, fix formatting --- .../tring/TringServiceImpl.java | 13 +------- src/rust/src/java/java.rs | 30 ++++++++++++------- src/rust/src/java/jtypes.rs | 30 ++++++++++--------- 3 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 937e89b0..8c406311 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -75,27 +75,16 @@ private void initiate() { } private void processAudioInputs() { - System.err.println("GOT CE"); + LOG.warning("Process Audio Inputs asked, not supported!"); MemorySegment audioInputs = tringlib_h.getAudioInputs(scope, callEndpoint,0); - System.err.println("GOT AI"); MemorySegment name = TringDevice.name$slice(audioInputs); - System.err.println("GOT NAME"); int namelen = (int)RString.len$get(name); - System.err.println("LEN = "+namelen); MemoryAddress namebuff = RString.buff$get(name); MemorySegment ofAddress = MemorySegment.ofAddress(namebuff, namelen, scope); ByteBuffer bb = ofAddress.asByteBuffer(); byte[] bname = new byte[namelen]; bb.get(bname, 0, (int)namelen); - // byte[] bname = bb.array(); - // byte[] bname = ofAddress.toArray(ValueLayout.JAVA_BYTE); -// byte[] bname = new byte[(int)namelen]; -// for (int i = 0; i < namelen; i++) { -// bname[i] = namebuff.get(ValueLayout.JAVA_BYTE, i); -// } - System.err.println("NAME = "+java.util.Arrays.toString(bname)); String myname = new String(bname); - System.err.println("hence, myname = "+myname); } @Override diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 08022894..3c0441bb 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -18,7 +18,9 @@ use crate::core::group_call::{GroupId, SignalingMessageUrgency}; use crate::core::signaling; use crate::core::util::ptr_as_mut; -use crate::java::jtypes::{JArrayByte, JArrayByte2D, JByteArray, JByteArray2D, JString, TringDevice}; +use crate::java::jtypes::{ + JArrayByte, JArrayByte2D, JByteArray, JByteArray2D, JString, TringDevice, +}; use crate::lite::http; use crate::lite::sfu::UserId; @@ -33,7 +35,9 @@ use crate::webrtc::media::{ use crate::webrtc::peer_connection::AudioLevel; -use crate::webrtc::peer_connection_factory::{self as pcf, AudioDevice, IceServer, PeerConnectionFactory}; +use crate::webrtc::peer_connection_factory::{ + self as pcf, AudioDevice, IceServer, PeerConnectionFactory, +}; use crate::webrtc::peer_connection_observer::NetworkRoute; fn init_logging() { @@ -738,12 +742,18 @@ pub unsafe extern "C" fn signalMessageSent(endpoint: i64, call_id: CallId) -> i6 pub unsafe extern "C" fn getAudioInputs(endpoint: i64, idx: u32) -> TringDevice<'static> { let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let devices = callendpoint - .peer_connection_factory - .get_audio_recording_devices().unwrap(); + .peer_connection_factory + .get_audio_recording_devices() + .unwrap(); // let mut answer: [TringDevice;16] = [TringDevice::empty();16]; let mut answer: TringDevice = TringDevice::empty(); for (i, device) in devices.iter().enumerate() { - let wd = TringDevice::from_fields(i as u32, device.name.clone(), device.unique_id.clone(), device.i18n_key.clone()); + let wd = TringDevice::from_fields( + i as u32, + device.name.clone(), + device.unique_id.clone(), + device.i18n_key.clone(), + ); if (i as u32 == idx) { answer = wd; } @@ -754,8 +764,6 @@ pub unsafe extern "C" fn getAudioInputs(endpoint: i64, idx: u32) -> TringDevice< #[no_mangle] pub unsafe extern "C" fn setAudioInput(endpoint: i64, index: u16) -> i64 { -// getAudioInputs(endpoint); -// getAudioOutputs(endpoint); let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); info!("Have to set audio_recordig_device to {}", index); endpoint @@ -768,13 +776,13 @@ pub unsafe extern "C" fn setAudioInput(endpoint: i64, index: u16) -> i64 { pub unsafe extern "C" fn getAudioOutputs(endpoint: i64) -> i64 { let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let devices = callendpoint - .peer_connection_factory - .get_audio_playout_devices(); - + .peer_connection_factory + .get_audio_playout_devices(); + for device in devices.iter() { info!("OUTDEVICE = {:#?}", device); } -1 + 1 } #[no_mangle] diff --git a/src/rust/src/java/jtypes.rs b/src/rust/src/java/jtypes.rs index 5316b1e2..88a1a430 100644 --- a/src/rust/src/java/jtypes.rs +++ b/src/rust/src/java/jtypes.rs @@ -19,16 +19,16 @@ impl JString { answer } -/* - pub fn from_string(src: String) -> Self { - let string_len = src.len(); - let mut string_bytes = src.as_bytes().as_mut_ptr(); - Self { - len: string_len, - buff: string_bytes + /* + pub fn from_string(src: String) -> Self { + let string_len = src.len(); + let mut string_bytes = src.as_bytes().as_mut_ptr(); + Self { + len: string_len, + buff: string_bytes + } } - } -*/ + */ } #[repr(C)] @@ -40,7 +40,6 @@ pub struct RString<'a> { } impl<'a> RString<'a> { - pub fn from_string(src: String) -> Self { let string_len = src.len(); let mut string_bytes = src.as_bytes().as_ptr(); @@ -52,7 +51,6 @@ impl<'a> RString<'a> { } } - #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct JArrayByte { @@ -217,7 +215,7 @@ impl<'a> TringDevice<'a> { index: 99, name: name, unique_id: unique_id, - int_key: int_key + int_key: int_key, } } @@ -232,7 +230,12 @@ impl<'a> TringDevice<'a> { int_key: src_int_key, } } - pub fn from_fields(index: u32, src_name:String, src_unique_id:String, src_i18n_key:String) -> Self { + pub fn from_fields( + index: u32, + src_name: String, + src_unique_id: String, + src_i18n_key: String, + ) -> Self { let src_name = RString::from_string(src_name); let src_unique_id = RString::from_string(src_unique_id); let src_int_key = RString::from_string(src_i18n_key); @@ -244,4 +247,3 @@ impl<'a> TringDevice<'a> { } } } - From c70ae62f43cb21201eb732a230406d4ca02f3be4 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Tue, 27 Dec 2022 20:42:36 +0100 Subject: [PATCH 69/74] Allocinjava (#15) * Do the video frame allocation in Java * Add test script --- .../tring/TringServiceImpl.java | 63 +++++++++++-------- src/java/tring/test.sh | 1 + .../privacyresearch/tringapi/TringBridge.java | 3 + .../tringapi/TringService.java | 2 + src/rust/src/java/java.rs | 23 ++++--- 5 files changed, 58 insertions(+), 34 deletions(-) create mode 100644 src/java/tring/test.sh diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 8c406311..d99b69e3 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -17,6 +17,7 @@ public class TringServiceImpl implements TringService { + static final int BANDWIDTH_QUALITY_HIGH = 2; private static final TringService instance = new TringServiceImpl(); private static boolean nativeSupport = false; private static long nativeVersion = 0; @@ -120,7 +121,7 @@ public void setSelfUuid(String uuid) { public void proceed(long callId, String iceUser, String icePwd, List ice) { MemorySegment icePack = toJByteArray2D(scope, ice); tringlib_h.setOutgoingAudioEnabled(callEndpoint, true); - tringlib_h.proceedCall(callEndpoint, callId, 0, 0, + tringlib_h.proceedCall(callEndpoint, callId, BANDWIDTH_QUALITY_HIGH, 0, toJString(scope, iceUser), toJString(scope, icePwd), icePack); } @@ -166,35 +167,41 @@ public long startOutgoingCall(long callId, String peerId, int localDeviceId, boo return callId; } + // for testing only + public void setArray() { + LOG.info("SET ARRAY"); + int CAP = 1000000; + for (int i = 0; i < 1000; i++) { + try (MemorySession rscope = MemorySession.openConfined()) { + MemorySegment segment = MemorySegment.allocateNative(CAP, scope); + tringlib_h.fillLargeArray(123, segment); + ByteBuffer bb = segment.asByteBuffer(); + byte[] bar = new byte[CAP]; + bb.get(bar, 0, CAP); + LOG.info("Got Array " + i + " sized " + bar.length); + } + } + LOG.info("DONE"); + } + @Override public TringFrame getRemoteVideoFrame(boolean skip) { - LOG.info("Get remote videoframe"); - try { - long a = tringlib_h.retrieveRemoteVideoFrame(callEndpoint); - int i = 0; - while (a == 0) { - Thread.sleep(50); - a = tringlib_h.retrieveRemoteVideoFrame(callEndpoint); - i++; - if (i > 40) return null; - } - LOG.info("Asked for a remote frame"); - synchronized (frameQueue) { - TringFrame frame = frameQueue.poll(); - if (frame == null) { - frameQueue.wait(15000); - frame = frameQueue.poll(); - } - LOG.info("Got a remote frame? " + frame); - if (frame != null) { - return frame; - } + int CAP = 5000000; + try (MemorySession rscope = MemorySession.openShared()) { + MemorySegment segment = MemorySegment.allocateNative(CAP, rscope); + long res = tringlib_h.fillRemoteVideoFrame(callEndpoint, segment, CAP); + if (res != 0) { + int w = (int) (res >> 16); + int h = (int) (res % (1 <<16)); + byte[] raw = new byte[w * h * 4]; + ByteBuffer bb = segment.asByteBuffer(); + bb.get(raw); + TringFrame answer = new TringFrame(w, h, -1, raw); + return answer; } - - } catch (InterruptedException ex) { - LOG.log(Level.SEVERE, null, ex); + } catch (Throwable t) { + t.printStackTrace(); } - LOG.info("Didn't receive a video frame from the other side in 15 seconds, return null"); return null; } @@ -372,10 +379,12 @@ Addressable createVideoFrameCallback() { return seg.address(); } + @Deprecated class VideoFrameCallbackImpl implements createCallEndpoint$videoFrameCallback { @Override public void apply(MemoryAddress opaque, int w, int h, long size) { - LOG.info("Got incoming video frame in Java layer"); + LOG.info("Got incoming video frame in Java layer, w = "+w+", h = " + h+", size = " + size); + System.err.println("Opaque = " + opaque); MemorySegment segment = MemorySegment.ofAddress(opaque, size, scope); byte[] raw = segment.toArray(ValueLayout.JAVA_BYTE); synchronized (frameQueue) { diff --git a/src/java/tring/test.sh b/src/java/tring/test.sh new file mode 100644 index 00000000..fcc7ca2a --- /dev/null +++ b/src/java/tring/test.sh @@ -0,0 +1 @@ +java --enable-preview -cp ../tringapi/target/tringapi-0.0.8-SNAPSHOT.jar:target/tring-0.0.11-SNAPSHOT-linux-x86_64.jar io.privacyresearch.tringtest.Main diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index 3f113092..590821ba 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -87,4 +87,7 @@ public void sendVideoFrame(int width, int height, int pixelFormat, byte[] raw) { service.sendVideoFrame(width, height, pixelFormat, raw); } + public void setArray() { + service.setArray(); + } } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index b9de79e3..c290f292 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -51,4 +51,6 @@ public default TringFrame getRemoteVideoFrame() { } public void sendVideoFrame(int w, int h, int pixelFormat, byte[] raw); + public void setArray(); + } diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index 3c0441bb..d68a8cc6 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -853,15 +853,25 @@ pub unsafe extern "C" fn sendVideoFrame( } #[no_mangle] -pub unsafe extern "C" fn retrieveRemoteVideoFrame(endpoint: i64) -> i64 { - let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); +pub unsafe extern "C" fn fillLargeArray(endpoint: i64, mybuffer: *mut u8) -> i64 { + let zero = *mybuffer.offset(0); + let first = *mybuffer.offset(1); + let second = *mybuffer.offset(12); + info!("VAL 1 = {} and VAL2 = {}", first, second); + *mybuffer.offset(12) = 13; + 1 +} + +#[no_mangle] +pub unsafe extern "C" fn fillRemoteVideoFrame(endpoint: i64, mybuffer: *mut u8, len: usize) -> i64 { info!("Have to retrieve remote video frame"); + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); let frame = endpoint.incoming_video_sink.pop(0); if let Some(frame) = frame { let frame = frame.apply_rotation(); let width: u32 = frame.width(); let height: u32 = frame.height(); - let myframe: &mut [u8] = &mut [0; 512000]; + let myframe: &mut [u8] = slice::from_raw_parts_mut(mybuffer, len); frame.to_rgba(myframe); info!( "Frame0 = {}, w = {}, h = {}", @@ -869,10 +879,9 @@ pub unsafe extern "C" fn retrieveRemoteVideoFrame(endpoint: i64) -> i64 { frame.width(), frame.height() ); - let o1 = Box::new(myframe); - let op = o1.as_ptr(); - (endpoint.videoFrameCallback)(op, width, height, 512000); - 1 + let mut size: i64 = (frame.width() << 16).into(); + size = size + frame.height() as i64; + size } else { 0 } From 2b8ce40fc666ace444a1800d1477e7b7e3124bc0 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Tue, 27 Dec 2022 20:45:10 +0100 Subject: [PATCH 70/74] Build 0.0.8 (tringapi) and 0.0.11 (tring) --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index a181f867..aed42ba5 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.11-SNAPSHOT + 0.0.11 jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.8-SNAPSHOT + 0.0.8 diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index 758701a3..6b273dfd 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.8-SNAPSHOT + 0.0.8 jar UTF-8 From 4258b3db808554e4e056a92cf1a941a2e204b391 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Wed, 28 Dec 2022 14:27:32 +0100 Subject: [PATCH 71/74] Bump versions to new snapshot version --- src/java/tring/pom.xml | 4 ++-- src/java/tringapi/pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java/tring/pom.xml b/src/java/tring/pom.xml index aed42ba5..9de8632d 100644 --- a/src/java/tring/pom.xml +++ b/src/java/tring/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tring - 0.0.11 + 0.0.12-SNAPSHOT jar UTF-8 @@ -14,7 +14,7 @@ io.privacyresearch tringapi - 0.0.8 + 0.0.9-SNAPSHOT diff --git a/src/java/tringapi/pom.xml b/src/java/tringapi/pom.xml index 6b273dfd..fdd89f8c 100644 --- a/src/java/tringapi/pom.xml +++ b/src/java/tringapi/pom.xml @@ -3,7 +3,7 @@ 4.0.0 io.privacyresearch tringapi - 0.0.8 + 0.0.9-SNAPSHOT jar UTF-8 From c498e6bc3866ff8c2937175e48a08452a386b8cf Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Mon, 27 Mar 2023 21:54:16 +0200 Subject: [PATCH 72/74] First steps for groupcalls --- .../privacyresearch/tring/TringServiceImpl.java | 11 +++++++++++ .../io/privacyresearch/tringapi/TringBridge.java | 5 +++++ .../privacyresearch/tringapi/TringService.java | 3 +++ src/rust/src/java/java.rs | 16 ++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index d99b69e3..4ab38983 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -100,6 +100,17 @@ receiverDeviceId, toJByteArray(scope, senderKey), toJByteArray(scope, receiverKe toJByteArray(scope, opaque), ageSec); } + + @Override + public void receivedOpaqueMessage(byte[] senderUuid, int senderDeviceId, + int localDeviceId, byte[] opaque, long age) { + tringlib_h.receivedOpaqueMessage(callEndpoint, + toJByteArray(scope, senderUuid), + senderDeviceId, + localDeviceId, + toJByteArray(scope, opaque), + age); + } @Override public void receivedAnswer(String peerId, long callId, int senderDeviceId, diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index 590821ba..e67f7dd7 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -66,6 +66,11 @@ public void receivedOffer(String peerId, long callId, int senderDeviceId, int re service.receivedOffer(peerId, callId, senderDeviceId, receiverDeviceId, senderKey, receiverKey, opaque); } + public void receivedOpaqueMessage(byte[] uuid, int senderDeviceId, int receiverDeviceId, + byte[] opaque, long ageMessage) { + service.receivedOpaqueMessage(uuid, senderDeviceId, receiverDeviceId, opaque, ageMessage); + } + public void receivedAnswer(String peerId, long callId, int receiverDeviceId, byte[] senderKey, byte[] receiverKey, byte[] opaque) { service.receivedAnswer(peerId, callId, receiverDeviceId, senderKey, receiverKey, opaque); diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index c290f292..a08e27c7 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -25,6 +25,9 @@ public interface TringService { public void receivedOffer(String peerId, long callId, int senderDeviceId, int receiverDeviceId, byte[] senderKey, byte[] receiverKey, byte[] opaque); + public void receivedOpaqueMessage(byte[] senderUuid, int senderDeviceId, + int localDeviceId, byte[] opaque, long age); + public void receivedAnswer(String peerId, long callId, int senderDeviceId, byte[] senderKey, byte[] receiverKey, byte[] opaque); public long startOutgoingCall(long callId, String peerId, int localDeviceId, boolean enableVideo); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index d68a8cc6..ca9c25af 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -583,6 +583,22 @@ pub unsafe extern "C" fn receivedOffer( 1 } +#[no_mangle] +pub unsafe extern "C" fn receivedOpaqueMessage( + endpoint: i64, + sender_juuid: JByteArray, + sender_device_id: DeviceId, + local_device_id: DeviceId, + opaque: JByteArray, + message_age_sec: u64) -> i64 { + info!("Create opaque message!"); + let message = opaque.to_vec_u8(); + let sender_uuid = sender_juuid.to_vec_u8(); + let callendpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + callendpoint.call_manager.received_call_message(sender_uuid, sender_device_id, local_device_id, message, Duration::from_secs(message_age_sec)); +1 +} + #[no_mangle] pub unsafe extern "C" fn receivedAnswer( endpoint: i64, From d5e000d2e001fca5c66625cec1c93f7c7bb71f11 Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 31 Mar 2023 14:26:12 +0200 Subject: [PATCH 73/74] Add entrypoint for httpclient --- src/rust/build.rs | 2 +- src/rust/src/java/java.rs | 130 +++++++++++++++++++++++++++++++++++++- 2 files changed, 130 insertions(+), 2 deletions(-) diff --git a/src/rust/build.rs b/src/rust/build.rs index 676bb01b..ed156580 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -27,7 +27,7 @@ fn main() { .with_crate(crate_dir) .with_language(cbindgen::Language::C) .generate() - .expect("uunable to generate bindings") + .expect("unable to generate bindings") .write_to_file("tringlib.h"); } let target = env::var("TARGET").unwrap(); diff --git a/src/rust/src/java/java.rs b/src/rust/src/java/java.rs index ca9c25af..bf7359b3 100644 --- a/src/rust/src/java/java.rs +++ b/src/rust/src/java/java.rs @@ -1,6 +1,7 @@ #![allow(unused_parens)] use std::collections::HashMap; +use std::convert::TryInto; use std::slice; use std::sync::atomic::AtomicBool; @@ -112,16 +113,26 @@ struct EventReporter { pub answerCallback: unsafe extern "C" fn(JArrayByte), pub offerCallback: unsafe extern "C" fn(JArrayByte), pub iceUpdateCallback: unsafe extern "C" fn(JArrayByte), + pub genericCallback: unsafe extern "C" fn(i32, JArrayByte), sender: Sender, report: Arc, } +fn string_to_bytes(v:String) -> Vec { + let mut answer:Vec = Vec::new(); + let ul = v.len(); + answer.extend_from_slice(&ul.to_le_bytes()); + answer.extend_from_slice(v.as_bytes()); + answer +} + impl EventReporter { fn new( statusCallback: extern "C" fn(u64, u64, i32, i32), answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), + genericCallback: extern "C" fn(i32, JArrayByte), sender: Sender, report: impl Fn() + Send + Sync + 'static, ) -> Self { @@ -130,6 +141,7 @@ impl EventReporter { answerCallback, offerCallback, iceUpdateCallback, + genericCallback, sender, report: Arc::new(report), } @@ -230,7 +242,106 @@ impl EventReporter { } } } - + Event::SendHttpRequest { + request_id, + request: + http::Request { + method, + url, + headers, + body, + }, + } => { + info!("NYI SendHttpReq"); + info!("Request id = {}", request_id); + info!("Requestmethod = {:?}", method); + info!("Requesturl = {:?}", url); + info!("Requestheaders = {:?}", headers); + info!("Requestbody = {:?}", body); + let mut payload:Vec = Vec::new(); + let rid = request_id as i32; + payload.extend_from_slice(&rid.to_le_bytes()); + + payload.push(method as u8); + + payload.extend(string_to_bytes(url)); + + let mut hdr:Vec = Vec::new(); + for (name, value) in headers.iter() { + hdr.extend(string_to_bytes(name.to_string())); + hdr.extend(string_to_bytes(value.to_string())); + } + let hdrlen = hdr.len(); + payload.extend_from_slice(&hdrlen.to_le_bytes()); + payload.extend(hdr); + + let bl = body.as_ref().map_or(0, |v| v.len()); + payload.extend_from_slice(&bl.to_le_bytes()); + payload.extend(body.unwrap_or_default()); + let data = JArrayByte::new(payload); + unsafe { + (self.genericCallback)(2, data); + } + } + Event::GroupUpdate(GroupUpdate::RequestMembershipProof(client_id)) => { + info!("NYI RMP"); + } + Event::GroupUpdate(GroupUpdate::RequestGroupMembers(client_id)) => { + info!("NYI RGM"); + } + Event::GroupUpdate(GroupUpdate::ConnectionStateChanged( + client_id, + connection_state, + )) => { + info!("NYI CSTATEChanged"); + } + Event::GroupUpdate(GroupUpdate::NetworkRouteChanged(client_id, network_route)) => { + info!("NYI NetworkRouteChanged"); + } + Event::GroupUpdate(GroupUpdate::JoinStateChanged(client_id, join_state)) => { + info!("NYI JoinStatesChanged"); + } + Event::GroupUpdate(GroupUpdate::RemoteDeviceStatesChanged( + client_id, + remote_device_states, + )) => { + info!("NYI RemoteDeviceStatesChanged"); + } + Event::GroupUpdate(GroupUpdate::PeekChanged { + client_id, + peek_info, + }) => { + info!("NYI PeekChanged"); + } + Event::GroupUpdate(GroupUpdate::PeekResult { + request_id, + peek_result, + }) => { + info!("NYI PeekResult"); + } + Event::GroupUpdate(GroupUpdate::Ended(client_id, reason)) => { + info!("NYI ENDED"); + } + Event::GroupUpdate(GroupUpdate::Ring { + group_id, + ring_id, + sender, + update, + }) => { + info!("[JV] GroupUpdate, gid = {:?}, ringid = {:?}, sender = {:?}, update = {:?}", group_id, ring_id, sender, update); + let mut payload:Vec = Vec::new(); + let glen: i32 = group_id.len().try_into().unwrap(); + payload.extend_from_slice(&glen.to_le_bytes()); + payload.extend(group_id); + let rid: i64 = ring_id.into(); + payload.extend_from_slice(&rid.to_le_bytes()); + payload.extend(sender); + payload.push(update as u8); + let data = JArrayByte::new(payload); + unsafe { + (self.genericCallback)(1, data); + } + } _ => { info!("[JV] unknownevent"); } @@ -362,6 +473,7 @@ impl http::Delegate for EventReporter { impl GroupUpdateHandler for EventReporter { fn handle_group_update(&self, update: GroupUpdate) -> Result<()> { + info!("Handle group update {:?}", update); self.send(Event::GroupUpdate(update))?; Ok(()) } @@ -390,6 +502,7 @@ impl CallEndpoint { answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), + genericCallback: extern "C" fn(i32, JArrayByte), videoFrameCallback: extern "C" fn(*const u8, u32, u32, size_t), ) -> Result { // Relevant for both group calls and 1:1 calls @@ -413,6 +526,7 @@ impl CallEndpoint { answerCallback, offerCallback, iceUpdateCallback, + genericCallback, events_sender, move || { info!("[JV] EVENT_REPORTER, NYI"); @@ -510,6 +624,7 @@ pub unsafe extern "C" fn createCallEndpoint( answerCallback: extern "C" fn(JArrayByte), offerCallback: extern "C" fn(JArrayByte), iceUpdateCallback: extern "C" fn(JArrayByte), + genericCallback: extern "C" fn(i32, JArrayByte), videoFrameCallback: extern "C" fn(*const u8, u32, u32, size_t), ) -> i64 { let call_endpoint = CallEndpoint::new( @@ -518,6 +633,7 @@ pub unsafe extern "C" fn createCallEndpoint( answerCallback, offerCallback, iceUpdateCallback, + genericCallback, videoFrameCallback, ) .unwrap(); @@ -902,3 +1018,15 @@ pub unsafe extern "C" fn fillRemoteVideoFrame(endpoint: i64, mybuffer: *mut u8, 0 } } + +#[no_mangle] +pub unsafe extern "C" fn peekGroupCall(endpoint: i64, + mp: JByteArray, +) -> i64 { + let membership_proof = mp.to_vec_u8(); + let endpoint = ptr_as_mut(endpoint as *mut CallEndpoint).unwrap(); + info!("peekGroupCall, not fully implemented"); + let sfu = String::from("https://sfu.voip.signal.org"); + endpoint.call_manager.peek_group_call(1, sfu, membership_proof, Vec::new()); + 1 +} From f3604214c32ff228ebd5d2f4be49aa572c61ca7f Mon Sep 17 00:00:00 2001 From: Johan Vos Date: Fri, 31 Mar 2023 16:45:30 +0200 Subject: [PATCH 74/74] prepare to send http request required for groupcall --- .../tring/TringServiceImpl.java | 42 ++++++++++++++++++- .../io/privacyresearch/tringapi/TringApi.java | 1 + .../privacyresearch/tringapi/TringBridge.java | 5 +++ .../tringapi/TringService.java | 1 + 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java index 4ab38983..22b92687 100644 --- a/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java +++ b/src/java/tring/src/main/java/io/privacyresearch/tring/TringServiceImpl.java @@ -8,7 +8,9 @@ import java.lang.foreign.MemorySession; import java.lang.foreign.ValueLayout; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -70,7 +72,9 @@ private void initiate() { scope = MemorySession.openShared(); tringlib_h.initRingRTC(toJString(scope, "Hello from Java")); this.callEndpoint = tringlib_h.createCallEndpoint(createStatusCallback(), - createAnswerCallback(), createOfferCallback(), createIceUpdateCallback(), + createAnswerCallback(), createOfferCallback(), + createIceUpdateCallback(), + createGenericCallback(), createVideoFrameCallback()); } @@ -178,6 +182,11 @@ public long startOutgoingCall(long callId, String peerId, int localDeviceId, boo return callId; } + @Override + public void peekGroupCall(byte[] membershipProof) { + tringlib_h.peekGroupCall(callEndpoint, toJByteArray(scope, membershipProof)); + } + // for testing only public void setArray() { LOG.info("SET ARRAY"); @@ -383,6 +392,37 @@ public void apply(MemorySegment icePack) { LOG.info("iceUpdate done!"); } } + MemorySegment createGenericCallback() { + GenericCallbackImpl sci = new GenericCallbackImpl(); + MemorySegment seg = createCallEndpoint$genericCallback.allocate(sci, scope); + return seg; + } + + class GenericCallbackImpl implements createCallEndpoint$genericCallback { + + @Override + public void apply(int opcode, MemorySegment data) { + byte[] bytes = fromJArrayByte(scope, data); + LOG.info("Got generic callback, opcode = " + opcode + " and data = " + Arrays.toString(bytes)); + if (opcode == 1) { + // groupId + ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN); + int groupIdLen = bb.getInt(); + byte[] groupId = new byte[groupIdLen]; + bb.get(groupId); + long ringId = bb.getLong(); + byte[] senderBytes = new byte[bb.remaining()-1]; + bb.get(senderBytes); + byte status = bb.get(); + System.err.println("GroupId = "+Arrays.toString(groupId)); + System.err.println("ringid = "+ringId); + System.err.println("senderBytes = "+Arrays.toString(senderBytes)); + System.err.println("status = "+status); + api.groupCallUpdateRing(groupId, ringId, senderBytes, status); + } + } + + } Addressable createVideoFrameCallback() { VideoFrameCallbackImpl sci = new VideoFrameCallbackImpl(); diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java index 1497dfd8..42837053 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringApi.java @@ -16,6 +16,7 @@ public interface TringApi { void iceUpdateCallback(List iceCandidates); + void groupCallUpdateRing(byte[] groupId, long ringId, byte[] senderBytes, byte status); // void getVideoFrame(int w, int h, byte[] raw); } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java index e67f7dd7..5b073b9d 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringBridge.java @@ -95,4 +95,9 @@ public void sendVideoFrame(int width, int height, int pixelFormat, byte[] raw) { public void setArray() { service.setArray(); } + + public void peekGroupCall(byte[] membershipProof) { + service.peekGroupCall(membershipProof); + } + } diff --git a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java index a08e27c7..9500f8f8 100644 --- a/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java +++ b/src/java/tringapi/src/main/java/io/privacyresearch/tringapi/TringService.java @@ -56,4 +56,5 @@ public default TringFrame getRemoteVideoFrame() { public void setArray(); + public void peekGroupCall(byte[] membershipProof); }