├── debian ├── compat ├── source │ └── format ├── README.Debian ├── changelog ├── config ├── copyright ├── install ├── templates ├── jigasi.service ├── rules ├── control ├── postrm └── init.d ├── src ├── main │ ├── resources │ │ ├── sounds │ │ │ ├── Alone.opus │ │ │ ├── LobbyWait.opus │ │ │ ├── MaxOccupants.opus │ │ │ ├── RecordingOn.opus │ │ │ ├── LiveStreamingOn.opus │ │ │ ├── LobbyMeetingEnd.opus │ │ │ ├── ParticipantLeft.opus │ │ │ ├── LiveStreamingOff.opus │ │ │ ├── LobbyAccessDenied.opus │ │ │ ├── ParticipantJoined.opus │ │ │ ├── RecordingStopped.opus │ │ │ └── LobbyAccessGranted.opus │ │ └── reference.conf │ └── java │ │ └── org │ │ └── jitsi │ │ └── jigasi │ │ ├── osgi │ │ ├── EmptyMasterPasswordInputServiceActivator.java │ │ ├── EmptyHidServiceActivator.java │ │ └── JigasiBundleConfig.java │ │ ├── transcription │ │ ├── TranslationResultListener.java │ │ ├── oracle │ │ │ ├── OracleServiceDisruptionException.java │ │ │ └── OracleRealtimeClientListener.java │ │ ├── TranscriptionEventListener.java │ │ ├── TranslationService.java │ │ ├── TranscriptionResultPublisher.java │ │ ├── PCMAudioSilenceMediaDevice.java │ │ ├── TranscribingAudioMixerMediaDevice.java │ │ ├── SpeechEvent.java │ │ ├── AbstractTranscriptionService.java │ │ ├── TranscriptionListener.java │ │ ├── GoogleCloudTranslationService.java │ │ ├── TranscriptionAlternative.java │ │ ├── Util.java │ │ ├── action │ │ │ └── ActionHandler.java │ │ ├── TranscriptPublisher.java │ │ ├── TranslationResult.java │ │ ├── TranscriptionRequest.java │ │ ├── WhisperConnectionPool.java │ │ ├── RemotePublisherTranscriptionHandler.java │ │ ├── SilenceFilter.java │ │ ├── LibreTranslateTranslationService.java │ │ ├── TranscriptEvent.java │ │ └── TranscriptionService.java │ │ ├── cmd │ │ └── ParseException.java │ │ ├── metrics │ │ └── JigasiMetricsContainer.java │ │ ├── version │ │ ├── VersionActivator.java │ │ ├── CurrentVersionImpl.java │ │ └── AbstractVersionActivator.java │ │ ├── GatewaySessionListener.java │ │ ├── GatewayListener.java │ │ ├── xmpp │ │ ├── extensions │ │ │ ├── RaiseHandExtension.java │ │ │ └── VisitorsPromotionResponseExtension.java │ │ └── CallControlAuthorizationException.java │ │ ├── util │ │ └── RegisterThread.java │ │ ├── rest │ │ ├── RESTUtil.java │ │ ├── TranscriptServerBundleActivator.java │ │ ├── MetricsHandler.java │ │ └── RESTBundleActivator.java │ │ ├── sounds │ │ └── SoundRateLimiter.java │ │ ├── visitor │ │ └── StompUtils.java │ │ ├── ServerSecurityAuthority.java │ │ ├── SsrcRewriter.java │ │ └── health │ │ └── Health.java ├── test │ ├── resources │ │ └── reference.conf │ └── java │ │ ├── org │ │ └── jitsi │ │ │ └── jigasi │ │ │ ├── CallListenerAdapter.java │ │ │ ├── GatewaySessionAsserts.java │ │ │ ├── GatewaySessions.java │ │ │ ├── OutCallListener.java │ │ │ ├── CallStateListener.java │ │ │ ├── cmd │ │ │ └── CmdLineArgsTest.java │ │ │ ├── rest │ │ │ └── RESTUtilTests.java │ │ │ ├── CallPeerStateListener.java │ │ │ └── OSGiHandler.java │ │ └── net │ │ └── java │ │ └── sip │ │ └── communicator │ │ └── service │ │ └── protocol │ │ └── mock │ │ ├── MockAccountID.java │ │ ├── MockPeerMediaHandler.java │ │ ├── MockCall.java │ │ ├── MockProtocolProviderFactoriesActivator.java │ │ ├── muc │ │ ├── MockRoomMember.java │ │ ├── MockMucShare.java │ │ └── MockMultiUserChatOpSet.java │ │ ├── MockProtocolProviderFactory.java │ │ ├── MockJitsiMeetTools.java │ │ ├── MockBasicTeleOpSet.java │ │ ├── MockCallPeer.java │ │ └── MockProtocolProvider.java └── assembly │ └── linux-x64-bin-archive.xml ├── .gitignore ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── ISSUE_TEMPLATE │ └── bug-report.md └── workflows │ └── maven.yml ├── SECURITY.md ├── script ├── example_handle_transcript_directory.sh ├── collect-dump-logs.sh ├── build_deb_package.sh ├── reconfigure_xmpp.sh └── graceful_shutdown.sh ├── jigasi.sh ├── lib └── logging.properties └── checkstyle.xml /debian/compat: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /debian/README.Debian: -------------------------------------------------------------------------------- 1 | Jitsi Gateway for SIP 2 | -------------------------------------------------------------------------------- /src/main/resources/sounds/Alone.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/Alone.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/LobbyWait.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/LobbyWait.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/MaxOccupants.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/MaxOccupants.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/RecordingOn.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/RecordingOn.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/LiveStreamingOn.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/LiveStreamingOn.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/LobbyMeetingEnd.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/LobbyMeetingEnd.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/ParticipantLeft.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/ParticipantLeft.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/LiveStreamingOff.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/LiveStreamingOff.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/LobbyAccessDenied.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/LobbyAccessDenied.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/ParticipantJoined.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/ParticipantJoined.opus -------------------------------------------------------------------------------- /src/main/resources/sounds/RecordingStopped.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/RecordingStopped.opus -------------------------------------------------------------------------------- /src/test/resources/reference.conf: -------------------------------------------------------------------------------- 1 | org.jitsi.jigasi { 2 | rest { 3 | port = 0 4 | } 5 | transcription { 6 | port = 0 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/sounds/LobbyAccessGranted.opus: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pibico/jigasi/master/src/main/resources/sounds/LobbyAccessGranted.opus -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /classes 2 | *.swp 3 | dist 4 | *.class 5 | *.jar 6 | 7 | .idea/* 8 | jigasi-home/ 9 | jigasi.iml 10 | .DS_Store 11 | 12 | target 13 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | jigasi (1.1-0-g9a369e3-1) unstable; urgency=low 2 | 3 | * Initial release 4 | 5 | -- Damian Minkov Tue, 29 Aug 2017 21:35:00 +0000 6 | -------------------------------------------------------------------------------- /src/main/resources/reference.conf: -------------------------------------------------------------------------------- 1 | org.jitsi.jigasi { 2 | rest { 3 | port = 8788 4 | tls-port = 8743 5 | } 6 | transcription { 7 | port = 0 8 | tls-port = 0 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /debian/config: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | # Source debconf library. 4 | . /usr/share/debconf/confmodule 5 | 6 | # sip account 7 | db_input critical jigasi/sip-account || true 8 | db_go 9 | 10 | # sip password 11 | db_input critical jigasi/sip-password || true 12 | db_go 13 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security 2 | 3 | ## Reporting security issuess 4 | 5 | We take security very seriously and develop all Jitsi projects to be secure and safe. 6 | 7 | If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org. 8 | 9 | **We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.** 10 | -------------------------------------------------------------------------------- /script/example_handle_transcript_directory.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # A bash script to receive the directory of a newly published 4 | # transcript and audio file. 5 | # 6 | # The first and only argument will always be the absolute path 7 | # to the new directory. 8 | # 9 | # The path to a script needs to be given in: 10 | # jigasi/jigasi-home/sip-communicator.properties 11 | 12 | abs_dir_path=$1 13 | echo "$abs_dir_path" >> dirs.txt -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: Jitsi Gateway to SIP 3 | Upstream-Contact: Emil Ivov 4 | Source: https://github.com/jitsi/jigasi 5 | 6 | Files: * 7 | Copyright: 2014-2018 Jitsi 8 | License: Apache 2.0 9 | 10 | License: Apache 2.0 11 | On Debian systems, the full text of the Apache licence 12 | version 2.0 can be found in the file 13 | '/usr/share/common-licenses/Apache-2.0'. 14 | -------------------------------------------------------------------------------- /debian/install: -------------------------------------------------------------------------------- 1 | target/dependency/* usr/share/jigasi/lib 2 | lib/logging.properties etc/jitsi/jigasi 3 | jigasi-home/sip-communicator.properties etc/jitsi/jigasi 4 | jigasi.jar usr/share/jigasi 5 | jigasi.sh usr/share/jigasi 6 | script/graceful_shutdown.sh usr/share/jigasi 7 | script/collect-dump-logs.sh usr/share/jigasi 8 | script/reconfigure_xmpp.sh usr/share/jigasi 9 | -------------------------------------------------------------------------------- /debian/templates: -------------------------------------------------------------------------------- 1 | Template: jigasi/sip-account 2 | Type: string 3 | Description: SIP username 4 | The jigasi package needs the SIP username that will be used to invite 5 | other SIP account into Jitsi Meet conferences. 6 | . 7 | Enter the FULL account name, i.e. sipnumber@sip-provider.name 8 | 9 | Template: jigasi/sip-password 10 | Type: password 11 | Description: SIP password 12 | Enter the password for the SIP account 13 | 14 | Template: jitsi-videobridge/jvb-hostname 15 | Type: string 16 | Description: Hostname: 17 | The jiconop package needs the DNS hostname of your instance. 18 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/osgi/EmptyMasterPasswordInputServiceActivator.java: -------------------------------------------------------------------------------- 1 | package org.jitsi.jigasi.osgi; 2 | 3 | import net.java.sip.communicator.service.credentialsstorage.*; 4 | import org.osgi.framework.*; 5 | 6 | public class EmptyMasterPasswordInputServiceActivator 7 | implements BundleActivator 8 | { 9 | @Override 10 | public void start(BundleContext context) throws Exception 11 | { 12 | context.registerService(MasterPasswordInputService.class, 13 | prevSuccess -> null, null); 14 | } 15 | 16 | @Override 17 | public void stop(BundleContext context) throws Exception 18 | { 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Before posting, please make sure you check https://community.jitsi.org 4 | 5 | --- 6 | 7 | *This Issue tracker is only for reporting bugs and tracking code related issues.* 8 | 9 | Before posting, please make sure you check community.jitsi.org to see if the same or similar bugs have already been discussed. General questions, installation help, and feature requests can also be posted to community.jitsi.org. 10 | 11 | ## Description 12 | --- 13 | 14 | ## Current behavior 15 | --- 16 | 17 | ## Expected Behavior 18 | --- 19 | 20 | ## Possible Solution 21 | --- 22 | 23 | ## Steps to reproduce 24 | --- 25 | 26 | # Environment details 27 | --- 28 | -------------------------------------------------------------------------------- /debian/jigasi.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Jitsi Gateway for SIP 3 | After=network.target 4 | 5 | [Service] 6 | EnvironmentFile=/etc/jitsi/jigasi/config 7 | Environment=LOGFILE=/var/log/jitsi/jigasi.log 8 | User=jigasi 9 | RuntimeDirectory=jigasi 10 | RuntimeDirectoryMode=0750 11 | PIDFile=/var/run/jigasi/jigasi.pid 12 | # more threads for this process 13 | TasksMax=65000 14 | # allow more open files for this process 15 | LimitNPROC=65000 16 | LimitNOFILE=65000 17 | ExecStart=/bin/bash -c "exec /usr/share/jigasi/jigasi.sh --host=$${JIGASI_HOST:-localhost} --domain=${JIGASI_HOSTNAME} --logdir=/var/log/jitsi --configdir=/etc/jitsi --configdirname=jigasi ${JIGASI_OPTS} < /dev/null >> ${LOGFILE} 2>&1" 18 | ExecStartPost=/bin/bash -c "echo $MAINPID > /var/run/jigasi/jigasi.pid" 19 | 20 | [Install] 21 | WantedBy=multi-user.target 22 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | # Uncomment this to turn on verbose mode. 4 | #export DH_VERBOSE=1 5 | #export DEB_VERBOSE_ALL=true 6 | 7 | # Disable debug package 8 | DEB_BUILD_OPTIONS=noddebs 9 | 10 | %: 11 | dh $@ 12 | 13 | override_dh_auto_clean: 14 | mvn -Dmaven.repo.local=${HOME}/.m2/repository clean 15 | 16 | override_dh_auto_configure: 17 | # do nothing 18 | 19 | override_dh_auto_test: 20 | # do nothing 21 | 22 | override_dh_auto_build: 23 | mvn -Dmaven.repo.local=${HOME}/.m2/repository -DskipTests -Dassembly.skipAssembly=true package 24 | mvn -Dmaven.repo.local=${HOME}/.m2/repository dependency:copy-dependencies -DincludeScope=runtime 25 | 26 | override_dh_install: 27 | mkdir debian/tmp 28 | cp target/jigasi*.jar debian/tmp/jigasi.jar 29 | dh_install 30 | 31 | override_dh_installinit: 32 | dh_installinit --noscripts 33 | 34 | override_dh_auto_install: 35 | dh_auto_install 36 | dh_installsystemd --restart-after-upgrade 37 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: jigasi 2 | Section: net 3 | Priority: extra 4 | Maintainer: Jitsi Team 5 | Uploaders: Emil Ivov , Damian Minkov 6 | Build-Depends: debhelper, dh-systemd, openjdk-11-jdk | openjdk-17-jdk, maven 7 | Standards-Version: 3.9.3 8 | Homepage: https://jitsi.org 9 | 10 | Package: jigasi 11 | Architecture: all 12 | Depends: ${misc:Depends}, openjdk-11-jre-headless | openjdk-11-jre | openjdk-17-jre-headless | openjdk-17-jre, openssl, ruby-hocon 13 | Description: Jitsi Gateway for SIP 14 | Jitsi Meet is a WebRTC JavaScript application that uses Jitsi 15 | Videobridge to provide high quality, scalable video conferences. 16 | . 17 | It is a web interface to Jitsi Videobridge for audio and video 18 | forwarding and relaying, configured to work with nginx 19 | . 20 | This package contains the jigasi (Jitsi Gateway for SIP) daemon, 21 | which allows SIP accounts to be invited in Jitsi Meet conferences. 22 | -------------------------------------------------------------------------------- /jigasi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | kernel="$(uname -s)" 4 | if [ $kernel == "Darwin" ] ; then 5 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" 6 | elif [ $kernel == "Linux" ] ; then 7 | SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" 8 | else 9 | echo "Unknown system : $kernel" 10 | exit 1 11 | fi 12 | 13 | mainClass="org.jitsi.jigasi.Main" 14 | cp=$(JARS=($SCRIPT_DIR/jigasi.jar $SCRIPT_DIR/lib/*.jar); IFS=:; echo "${JARS[*]}") 15 | libs="$SCRIPT_DIR/lib" 16 | logging_config="$SCRIPT_DIR/lib/logging.properties" 17 | 18 | # if there is a logging config file in lib folder use it (running from source) 19 | if [ -f $logging_config ]; then 20 | LOGGING_CONFIG_PARAM="-Djava.util.logging.config.file=$logging_config" 21 | fi 22 | 23 | if [ -z "$JIGASI_MAX_MEMORY" ]; then JIGASI_MAX_MEMORY=3072m; fi 24 | 25 | LD_LIBRARY_PATH=$libs exec java -Xmx$JIGASI_MAX_MEMORY -Djdk.net.usePlainDatagramSocketImpl=true -Djava.library.path=$libs $LOGGING_CONFIG_PARAM $JAVA_SYS_PROPS -cp $cp $mainClass $@ 26 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranslationResultListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | 21 | public interface TranslationResultListener 22 | { 23 | 24 | /** 25 | * Notify this listener that a TranslationResult has come in. 26 | * 27 | * @param result the result which has come in 28 | */ 29 | void notify(TranslationResult result); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/oracle/OracleServiceDisruptionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.jitsi.jigasi.transcription.oracle; 20 | 21 | public class OracleServiceDisruptionException extends Exception 22 | { 23 | public OracleServiceDisruptionException(String message) { 24 | super(message); 25 | } 26 | public OracleServiceDisruptionException(Throwable e){ 27 | super(e); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | pull_request: 8 | branches: [ master ] 9 | push: 10 | branches: [ master ] 11 | 12 | env: 13 | # Java version to use for the release 14 | RELEASE_JAVA_VERSION: 11 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | 21 | strategy: 22 | matrix: 23 | java: [ 11, 17, 21 ] 24 | 25 | name: Java ${{ matrix.java }} 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | - name: Set up Java ${{ matrix.java }} 30 | uses: actions/setup-java@v4 31 | with: 32 | distribution: temurin 33 | java-version: ${{ matrix.java }} 34 | cache: maven 35 | 36 | - name: Build with Maven 37 | run: mvn verify -B -Pcoverage 38 | 39 | - name: Upload coverage report 40 | if: matrix.java == env.RELEASE_JAVA_VERSION 41 | uses: codecov/codecov-action@v4 42 | with: 43 | token: ${{ secrets.CODECOV_TOKEN }} 44 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/cmd/ParseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2015 - present, 8x8 Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jitsi.jigasi.cmd; 17 | 18 | /** 19 | * An exception thrown when unrecoverable parsing error occurs. 20 | * 21 | * @author Pawel Domas 22 | */ 23 | public class ParseException 24 | extends Exception 25 | { 26 | /** 27 | * Creates new instance of ParseException. 28 | * @param message parse exception message. 29 | */ 30 | public ParseException(String message) 31 | { 32 | super(message); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/metrics/JigasiMetricsContainer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2024 - present 8x8, Inc 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.metrics; 19 | 20 | import io.prometheus.client.*; 21 | import org.jitsi.metrics.*; 22 | 23 | public class JigasiMetricsContainer extends MetricsContainer 24 | { 25 | public final static JigasiMetricsContainer INSTANCE = new JigasiMetricsContainer(); 26 | 27 | private JigasiMetricsContainer() 28 | { 29 | super(CollectorRegistry.defaultRegistry, "jitsi_jigasi"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/logging.properties: -------------------------------------------------------------------------------- 1 | 2 | handlers= java.util.logging.ConsoleHandler 3 | #handlers= java.util.logging.ConsoleHandler, com.agafua.syslog.SyslogHandler 4 | #handlers= java.util.logging.ConsoleHandler, io.sentry.jul.SentryHandler 5 | 6 | java.util.logging.ConsoleHandler.level = ALL 7 | java.util.logging.ConsoleHandler.formatter = org.jitsi.utils.logging2.JitsiLogFormatter 8 | 9 | .level=INFO 10 | net.sf.level=SEVERE 11 | net.java.sip.communicator.plugin.reconnectplugin.level=FINE 12 | org.ice4j.level=SEVERE 13 | org.jitsi.impl.neomedia.level=SEVERE 14 | net.java.sip.communicator.impl.protocol.sip.level=SEVERE 15 | 16 | # Do not worry about missing strings 17 | net.java.sip.communicator.service.resources.AbstractResourcesService.level=SEVERE 18 | 19 | # Does not print roster warning on account removals 20 | org.jivesoftware.smack.roster.Roster.level=SEVERE 21 | 22 | #net.java.sip.communicator.service.protocol.level=ALL 23 | 24 | # Syslog (uncomment handler to use) 25 | com.agafua.syslog.SyslogHandler.transport = udp 26 | com.agafua.syslog.SyslogHandler.facility = local0 27 | com.agafua.syslog.SyslogHandler.port = 514 28 | com.agafua.syslog.SyslogHandler.hostname = localhost 29 | 30 | # Sentry (uncomment handler to use) 31 | io.sentry.jul.SentryHandler.level=WARNING 32 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/version/VersionActivator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2019 - present, 8x8 Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jitsi.jigasi.version; 17 | 18 | import org.jitsi.utils.version.*; 19 | 20 | /** 21 | * Extends {@link AbstractVersionActivator} in order to provider the 22 | * {@code VersionService} implementation for the Jicofo. 23 | * 24 | * @author Boris Grozev 25 | */ 26 | public class VersionActivator 27 | extends AbstractVersionActivator 28 | { 29 | /** 30 | * {@inheritDoc} 31 | */ 32 | @Override 33 | protected Version getCurrentVersion() 34 | { 35 | return CurrentVersionImpl.VERSION; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/oracle/OracleRealtimeClientListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package org.jitsi.jigasi.transcription.oracle; 20 | import com.oracle.bmc.aispeech.model.*; 21 | 22 | public interface OracleRealtimeClientListener 23 | { 24 | void onClose(int statusCode, String statusMessage); 25 | 26 | void onAckMessage(RealtimeMessageAckAudio ackMessage); 27 | 28 | void onResult(RealtimeMessageResult result); 29 | 30 | void onError(Throwable error); 31 | 32 | void onConnect(); 33 | 34 | void onConnectMessage(RealtimeMessageConnect connectMessage); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscriptionEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | /** 21 | * A listener object which will be notified when a TranscriptEvent is created. 22 | * 23 | * @author Damian Minkov 24 | */ 25 | public interface TranscriptionEventListener 26 | { 27 | /** 28 | * Notifies for newly create TranscriptEvent. 29 | * @param transcriber the transcriber creating the event. 30 | * @param event the newly created event. 31 | */ 32 | public void notify(Transcriber transcriber, TranscriptEvent event); 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/CallListenerAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import net.java.sip.communicator.service.protocol.event.*; 21 | 22 | /** 23 | * The stub of {@link CallListener}, so that we don't have to implement all 24 | * methods whenever we want to listen for only one event. 25 | * 26 | * @author Pawel Domas 27 | */ 28 | public class CallListenerAdapter 29 | implements CallListener 30 | { 31 | @Override 32 | public void incomingCallReceived(CallEvent event) 33 | { 34 | 35 | } 36 | 37 | @Override 38 | public void outgoingCallCreated(CallEvent event) 39 | { 40 | 41 | } 42 | 43 | @Override 44 | public void callEnded(CallEvent event) 45 | { 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranslationService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | /** 21 | * This interface allows for translation text from the source language to the 22 | * target language. 23 | * 24 | * @author Praveen Kumar Gupta 25 | */ 26 | public interface TranslationService 27 | { 28 | 29 | /** 30 | * Translates the given text from the source language to target language. 31 | * 32 | * @param sourceText the text to be translated. 33 | * @param sourceLang the language of the text to be translated. 34 | * @param targetLang the target language for translating the text. 35 | * @return the translated string of the text. 36 | */ 37 | String translate(String sourceText, String sourceLang, String targetLang); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/osgi/EmptyHidServiceActivator.java: -------------------------------------------------------------------------------- 1 | package org.jitsi.jigasi.osgi; 2 | 3 | import java.util.*; 4 | import net.java.sip.communicator.service.hid.*; 5 | import org.osgi.framework.*; 6 | 7 | public class EmptyHidServiceActivator 8 | implements BundleActivator 9 | { 10 | @Override 11 | public void start(BundleContext bundleContext) throws Exception 12 | { 13 | bundleContext.registerService(HIDService.class, new HIDService() 14 | { 15 | @Override 16 | public void keyPress(int keycode) 17 | { 18 | } 19 | 20 | @Override 21 | public void keyRelease(int keycode) 22 | { 23 | } 24 | 25 | @Override 26 | public void keyPress(char key) 27 | { 28 | } 29 | 30 | @Override 31 | public void keyRelease(char key) 32 | { 33 | } 34 | 35 | @Override 36 | public void mousePress(int btns) 37 | { 38 | } 39 | 40 | @Override 41 | public void mouseRelease(int btns) 42 | { 43 | } 44 | 45 | @Override 46 | public void mouseMove(int x, int y) 47 | { 48 | } 49 | 50 | @Override 51 | public void mouseWheel(int rotation) 52 | { 53 | } 54 | }, new Hashtable<>()); 55 | } 56 | 57 | @Override 58 | public void stop(BundleContext bundleContext) throws Exception 59 | { 60 | } 61 | } -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscriptionResultPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.jigasi.*; 21 | 22 | /** 23 | * This interface is used to send a message to the chatRoom of a jitsi-meet 24 | * conference 25 | * 26 | * @author Nik Vaessen 27 | */ 28 | public interface TranscriptionResultPublisher 29 | { 30 | /** 31 | * Publish the given TranscriptionResult to the given ChatRoom 32 | * 33 | * @param jvbConference the meeting room 34 | * @param result the result 35 | */ 36 | void publish(JvbConference jvbConference, TranscriptionResult result); 37 | 38 | /** 39 | * Publish the given TranslationResult to the given ChatRoom 40 | * 41 | * @param jvbConference the meeting room 42 | * @param result the result 43 | */ 44 | void publish(JvbConference jvbConference, TranslationResult result); 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/GatewaySessionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | 22 | /** 23 | * Class used to listen for various {@link AbstractGatewaySession} state 24 | * changes. 25 | * 26 | * @author Pawel Domas 27 | * @author Nik Vaessen 28 | */ 29 | public interface GatewaySessionListener 30 | { 31 | /** 32 | * Called when a AbstractGatewaySession has joined the MUC 33 | * 34 | * @param source the {@link AbstractGatewaySession} on which the event 35 | * takes place. 36 | */ 37 | void onJvbRoomJoined(T source); 38 | 39 | /** 40 | * Called when a AbstractGatewaySession has joined the lobby MUC 41 | * 42 | * @param lobbyRoom the {@link ChatRoom} representing the lobby room. 43 | */ 44 | void onLobbyWaitReview(ChatRoom lobbyRoom); 45 | } 46 | -------------------------------------------------------------------------------- /checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/PCMAudioSilenceMediaDevice.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2023 8x8 Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.impl.neomedia.device.*; 21 | import org.jitsi.service.neomedia.*; 22 | 23 | import javax.media.*; 24 | import javax.media.protocol.*; 25 | 26 | public class PCMAudioSilenceMediaDevice 27 | extends AudioSilenceMediaDevice 28 | { 29 | protected CaptureDevice createCaptureDevice() 30 | { 31 | return new PCMAudioSilenceCaptureDevice(false); 32 | } 33 | 34 | protected Processor createPlayer(DataSource dataSource) 35 | { 36 | return null; 37 | } 38 | 39 | public MediaDeviceSession createSession() 40 | { 41 | return new AudioMediaDeviceSession(this) 42 | { 43 | protected Player createPlayer(DataSource dataSource) 44 | { 45 | return null; 46 | } 47 | }; 48 | } 49 | 50 | public MediaDirection getDirection() 51 | { 52 | return MediaDirection.SENDRECV; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscribingAudioMixerMediaDevice.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.impl.neomedia.device.*; 21 | 22 | /** 23 | * AudioMixerMediaDevice which adds a {@link ReceiveStreamBufferListener} to 24 | * itself which gets all the audio data going to the AudioMixer. 25 | * 26 | * This audio can be distinguished by participant by looking at the SSRC 27 | * of the {@link javax.media.rtp.ReceiveStream} providing the audio 28 | * 29 | * @author Nik Vaessen 30 | */ 31 | public class TranscribingAudioMixerMediaDevice 32 | extends AudioMixerMediaDevice 33 | { 34 | 35 | /** 36 | * Create a new MediaDevice which does not output any audio 37 | * and has a listener for all other audio 38 | */ 39 | public TranscribingAudioMixerMediaDevice( 40 | AudioSilenceMediaDevice device, 41 | ReceiveStreamBufferListener listener) 42 | { 43 | super(device); 44 | super.setReceiveStreamBufferListener(listener); 45 | } 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/SpeechEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import java.time.*; 21 | 22 | /** 23 | * A SpeechEvent extends a normal TranscriptEvent by including a 24 | * TranscriptionResult 25 | * 26 | * @author Nik Vaessen 27 | */ 28 | public class SpeechEvent 29 | extends TranscriptEvent 30 | { 31 | /** 32 | * The transcriptionResult 33 | */ 34 | private TranscriptionResult result; 35 | 36 | /** 37 | * Create a ResultHolder with a given TranscriptionResult and timestamp 38 | * 39 | * @param result the result which was received 40 | */ 41 | SpeechEvent(TranscriptionResult result) 42 | { 43 | super(result.getTimeStamp(), result.getParticipant(), Transcript.TranscriptEventType.SPEECH); 44 | this.result = result; 45 | } 46 | 47 | /** 48 | * Get the TranscriptionResult this holder is holding 49 | * 50 | * @return the result 51 | */ 52 | public TranscriptionResult getResult() 53 | { 54 | return result; 55 | } 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/GatewayListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | /** 21 | * Class used to listen for various {@link SipGateway} state changes. 22 | * 23 | * @author Damian Minkov 24 | * @author Nik Vaessen 25 | */ 26 | public interface GatewayListener 27 | { 28 | /** 29 | * Called when new session is added to the list of active sessions. 30 | * @param session the session that was added. 31 | */ 32 | default void onSessionAdded(AbstractGatewaySession session) 33 | {} 34 | 35 | /** 36 | * Called when a session is removed from the list of active sessions. 37 | * @param session the session that was removed. 38 | */ 39 | default void onSessionRemoved(AbstractGatewaySession session) 40 | {} 41 | 42 | /** 43 | * Called when a session failed to establish. 44 | * @param session the session that failed. 45 | */ 46 | default void onSessionFailed(AbstractGatewaySession session) 47 | {} 48 | 49 | /** 50 | * Called when the gateway is ready to create new sessions. 51 | */ 52 | default void onReady() 53 | {} 54 | } 55 | -------------------------------------------------------------------------------- /script/collect-dump-logs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # script that creates an archive in current folder 4 | # containing the heap and thread dump and the current log file 5 | 6 | JAVA_HEAPDUMP_PATH="/tmp/java_*.hprof" 7 | STAMP=`date +%Y-%m-%d-%H%M` 8 | PID_PATH="/var/run/jigasi.pid" 9 | JIGASI_USER="jigasi" 10 | JIGASI_UID=`id -u $JIGASI_USER` 11 | RUNNING="" 12 | unset PID 13 | 14 | #Find any crashes in /var/crash from our user in the past 20 minutes, if they exist 15 | CRASH_FILES=$(find /var/crash -name '*.crash' -uid $JIGASI_UID -mmin -20 -type f) 16 | 17 | # for systemd we use different pid file 18 | if [ ! -f $PID_PATH ]; then 19 | PID_PATH="/var/run/jigasi/jigasi.pid" 20 | fi 21 | 22 | [ -e $PID_PATH ] && PID=$(cat $PID_PATH) 23 | if [ ! -z $PID ]; then 24 | ps -p $PID | grep -q java 25 | [ $? -eq 0 ] && RUNNING="true" 26 | fi 27 | if [ ! -z $RUNNING ]; then 28 | echo "Jigasi pid $PID" 29 | THREADS_FILE="/tmp/stack-${STAMP}-${PID}.threads" 30 | HEAP_FILE="/tmp/heap-${STAMP}-${PID}.bin" 31 | sudo -u $JIGASI_USER jstack ${PID} > ${THREADS_FILE} 32 | sudo -u $JIGASI_USER jmap -dump:live,format=b,file=${HEAP_FILE} ${PID} 33 | tar zcvf jigasi-dumps-${STAMP}-${PID}.tgz ${THREADS_FILE} ${HEAP_FILE} ${CRASH_FILES} /var/log/jitsi/jigasi.log /tmp/hs_err_* 34 | rm ${HEAP_FILE} ${THREADS_FILE} 35 | else 36 | ls $JAVA_HEAPDUMP_PATH >/dev/null 2>&1 37 | if [ $? -eq 0 ]; then 38 | echo "Jigasi not running, but previous heap dump found." 39 | tar zcvf jigasi-dumps-${STAMP}-crash.tgz $JAVA_HEAPDUMP_PATH ${CRASH_FILES} /var/log/jitsi/jigasi.log /tmp/hs_err_* 40 | rm ${JAVA_HEAPDUMP_PATH} 41 | else 42 | echo "Jigasi not running, no previous dump found. Including logs only." 43 | tar zcvf jigasi-dumps-${STAMP}-crash.tgz ${CRASH_FILES} /var/log/jitsi/jigasi.log /tmp/hs_err_* 44 | fi 45 | fi 46 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/AbstractTranscriptionService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.impl.neomedia.device.*; 21 | 22 | public abstract class AbstractTranscriptionService 23 | implements TranscriptionService 24 | { 25 | protected TranscribingAudioMixerMediaDevice mediaDevice = null; 26 | 27 | /** 28 | * Get the MediaDevice this transcriber is listening to for audio 29 | * 30 | * @return the AudioMixerMediaDevice which should receive all audio needed 31 | * to be transcribed 32 | */ 33 | public AudioMixerMediaDevice getMediaDevice(ReceiveStreamBufferListener listener) 34 | { 35 | if (this.mediaDevice == null) 36 | { 37 | this.mediaDevice = new TranscribingAudioMixerMediaDevice(new AudioSilenceMediaDevice(), listener); 38 | } 39 | 40 | return this.mediaDevice; 41 | } 42 | 43 | /** 44 | * Returns true if the SilenceFilter should be disabled for this 45 | * TranscriptionService. 46 | */ 47 | public boolean disableSilenceFilter() 48 | { 49 | return false; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/assembly/linux-x64-bin-archive.xml: -------------------------------------------------------------------------------- 1 | 5 | linux-x64-bin-archive 6 | 7 | zip 8 | 9 | true 10 | ${project.artifactId}-linux-x64-${project.version} 11 | 12 | 13 | lib 14 | runtime 15 | false 16 | false 17 | 18 | 19 | 20 | 21 | ${project.basedir}/target/${project.artifactId}-${project.version}.jar 22 | ${file.separator} 23 | jigasi.jar 24 | 25 | 26 | 27 | 28 | ${project.basedir}/lib 29 | lib 30 | 31 | **/*.jar 32 | 33 | 34 | 35 | ${project.basedir} 36 | ${file.separator} 37 | 755 38 | 39 | jigasi.sh 40 | 41 | 42 | 43 | ${project.basedir}/script 44 | ${file.separator} 45 | 755 46 | 47 | graceful_shutdown.sh 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/xmpp/extensions/RaiseHandExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.xmpp.extensions; 19 | 20 | import org.jitsi.xmpp.extensions.*; 21 | import org.jivesoftware.smack.packet.*; 22 | 23 | /** 24 | * Added to presence to raise/lower hand. 25 | */ 26 | public class RaiseHandExtension 27 | extends AbstractPacketExtension 28 | { 29 | /** 30 | * The namespace of this packet extension. 31 | */ 32 | public static final String NAMESPACE = "jabber:client"; 33 | 34 | /** 35 | * XML element name of this packet extension. 36 | */ 37 | public static final String ELEMENT_NAME = "jitsi_participant_raisedHand"; 38 | 39 | /** 40 | * Creates a {@link org.jitsi.jigasi.xmpp.extensions.RaiseHandExtension} instance. 41 | */ 42 | public RaiseHandExtension() 43 | { 44 | super(NAMESPACE, ELEMENT_NAME); 45 | } 46 | 47 | /** 48 | * Sets user's raise hand status. 49 | * 50 | * @param value true or false which raise hand status of the user. 51 | */ 52 | public ExtensionElement setRaisedHandValue(Boolean value) 53 | { 54 | setText(value ? String.valueOf(System.currentTimeMillis()) : null); 55 | 56 | return this; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /script/build_deb_package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | set -e 4 | 5 | # Make sure you have the following environment variables set, example: 6 | # export DEBFULLNAME="Jitsi Team" 7 | # export DEBEMAIL="dev@jitsi.org" 8 | # You need package devscripts installed (command dch). 9 | 10 | echo "===================================================================" 11 | echo " Building DEB packages... " 12 | echo "===================================================================" 13 | 14 | SCRIPT_FOLDER=$(dirname "$0") 15 | cd "$SCRIPT_FOLDER/.." 16 | 17 | # Let's get version from maven 18 | MVNVER=$(xmllint --xpath "/*[local-name()='project']/*[local-name()='version']/text()" pom.xml) 19 | TAG_NAME="v${MVNVER/-SNAPSHOT/}" 20 | 21 | echo "Current tag name: $TAG_NAME" 22 | 23 | if ! git rev-parse "$TAG_NAME" >/dev/null 2>&1 24 | then 25 | git tag -a "$TAG_NAME" -m "Tagged automatically by Jenkins" 26 | git push origin "$TAG_NAME" 27 | else 28 | echo "Tag: $TAG_NAME already exists." 29 | fi 30 | 31 | VERSION_FULL=$(git describe --match "v[0-9\.]*" --long) 32 | echo "Full version: ${VERSION_FULL}" 33 | 34 | VERSION=${VERSION_FULL:1} 35 | echo "Package version: ${VERSION}" 36 | 37 | REV=$(git log --pretty=format:'%h' -n 1) 38 | dch -v "$VERSION-1" "Build from git. $REV" 39 | dch -D unstable -r "" 40 | 41 | # We need to make sure all dependencies are downloaded before start building 42 | # the debian package 43 | mvn dependency:resolve 44 | 45 | # sets the version in the pom file so it will propagte to resulting jar 46 | mvn versions:set -DnewVersion="${VERSION}" 47 | 48 | # now build the deb 49 | dpkg-buildpackage -tc -us -uc -A -d 50 | 51 | # clean the current changes as dch had changed the change log 52 | git checkout debian/changelog 53 | git checkout pom.xml 54 | 55 | echo "Here are the resulting files in $(pwd ..)" 56 | echo "-----" 57 | ls -l ../{*.changes,*.deb,*.buildinfo} 58 | echo "-----" 59 | 60 | # Let's try deploying 61 | cd .. 62 | ([ ! -x deploy.sh ] || ./deploy.sh) 63 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/util/RegisterThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.util; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | import org.jitsi.jigasi.*; 22 | import org.jitsi.utils.logging.Logger; 23 | 24 | /** 25 | * Thread does the job of registering given ProtocolProviderService. 26 | * 27 | * @author Pawel Domas 28 | * @author George Politis 29 | */ 30 | public class RegisterThread 31 | extends Thread 32 | { 33 | /** 34 | * The logger. 35 | */ 36 | private final static Logger logger 37 | = Logger.getLogger(RegisterThread.class); 38 | 39 | private final ProtocolProviderService pps; 40 | 41 | private final String password; 42 | 43 | public RegisterThread(ProtocolProviderService pps) 44 | { 45 | this(pps, null); 46 | } 47 | 48 | public RegisterThread(ProtocolProviderService pps, String password) 49 | { 50 | this.pps = pps; 51 | this.password = password; 52 | } 53 | 54 | @Override 55 | public void run() 56 | { 57 | try 58 | { 59 | pps.register(new ServerSecurityAuthority(pps, password)); 60 | } 61 | catch (OperationFailedException e) 62 | { 63 | logger.error(e, e); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/xmpp/extensions/VisitorsPromotionResponseExtension.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.xmpp.extensions; 19 | 20 | import org.jitsi.xmpp.extensions.*; 21 | import org.jitsi.xmpp.extensions.visitors.*; 22 | 23 | /** 24 | * Receive promotion response after raising hand while being a visitor. 25 | */ 26 | public class VisitorsPromotionResponseExtension 27 | extends AbstractPacketExtension 28 | { 29 | /** 30 | * Name space of start muted packet extension. 31 | */ 32 | public static final String NAMESPACE = VisitorsIq.NAMESPACE; 33 | 34 | /** 35 | * XML element name of this packet extension. 36 | */ 37 | public static final String ELEMENT = "promotion-response"; 38 | 39 | /** 40 | * Creates a {@link org.jitsi.jigasi.xmpp.extensions.VisitorsPromotionResponseExtension} instance. 41 | */ 42 | public VisitorsPromotionResponseExtension() 43 | { 44 | super(NAMESPACE, ELEMENT); 45 | } 46 | 47 | public String getJid() 48 | { 49 | return getAttributeAsString("jid"); 50 | } 51 | 52 | public String getUsername() 53 | { 54 | return getAttributeAsString("username"); 55 | } 56 | 57 | public boolean isAllowed() 58 | { 59 | return Boolean.parseBoolean(getAttributeAsString("allow")); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/GatewaySessionAsserts.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import static org.junit.jupiter.api.Assertions.assertTrue; 21 | 22 | import net.java.sip.communicator.service.protocol.*; 23 | 24 | /** 25 | * Class encapsulates some assertions about {@link SipGatewaySession}. 26 | * 27 | * @author Pawel Domas 28 | * @author Nik Vaessen 29 | */ 30 | public class GatewaySessionAsserts 31 | implements GatewaySessionListener 32 | { 33 | @Override 34 | public void onJvbRoomJoined(AbstractGatewaySession source) 35 | { 36 | synchronized (this) 37 | { 38 | this.notifyAll(); 39 | } 40 | } 41 | 42 | @Override 43 | public void onLobbyWaitReview(ChatRoom lobbyRoom) 44 | {} 45 | 46 | public void assertJvbRoomJoined(AbstractGatewaySession session, long timeout) 47 | throws InterruptedException 48 | { 49 | synchronized (this) 50 | { 51 | session.addListener(this); 52 | 53 | ChatRoom room = session.getJvbChatRoom(); 54 | 55 | if (room == null || !room.isJoined()) 56 | { 57 | this.wait(timeout); 58 | } 59 | 60 | session.removeListener(this); 61 | 62 | assertTrue(session.getJvbChatRoom().isJoined()); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/GatewaySessions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import java.util.*; 21 | 22 | public class GatewaySessions 23 | implements GatewayListener 24 | { 25 | private final Object syncRoot = new Object(); 26 | 27 | private List sessions = null; 28 | 29 | private final SipGateway gateway; 30 | 31 | public GatewaySessions(SipGateway gateway) 32 | { 33 | this.gateway = gateway; 34 | 35 | this.gateway.addGatewayListener(this); 36 | } 37 | 38 | @Override 39 | public void onSessionAdded(AbstractGatewaySession session) 40 | { 41 | sessions = gateway.getActiveSessions(); 42 | 43 | synchronized (syncRoot) 44 | { 45 | syncRoot.notifyAll(); 46 | } 47 | } 48 | 49 | /** 50 | * Obtain sessions 51 | * @param timeout the time to wait to receive the sessions 52 | * @return list of sip gw sessions 53 | */ 54 | public List getSessions(long timeout) 55 | throws InterruptedException 56 | { 57 | if (sessions == null) 58 | { 59 | synchronized (syncRoot) 60 | { 61 | syncRoot.wait(timeout); 62 | } 63 | } 64 | 65 | this.gateway.removeGatewayListener(this); 66 | 67 | return sessions; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscriptionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | /** 21 | * A listener object which will be notified when a Transcription receives 22 | * a new Transcription result. This can for example be used to push new 23 | * results to a conference to give participants immediate results 24 | * 25 | * @author Nik Vaessen 26 | */ 27 | public interface TranscriptionListener 28 | { 29 | /** 30 | * Notify this listener that a TranscriptionResult has come in 31 | * 32 | * @param result the result which has come in 33 | */ 34 | void notify(TranscriptionResult result); 35 | 36 | /** 37 | * Notify this listener that no new results will come in as 38 | * the transcription has been completed 39 | */ 40 | void completed(); 41 | 42 | /** 43 | * Notify this listener that the transcriptions has failed and no new 44 | * results will come in. 45 | * @param reason the failure reason 46 | */ 47 | void failed(FailureReason reason); 48 | 49 | /** 50 | * Passed as an argument to {@link #failed(FailureReason)}. 51 | */ 52 | enum FailureReason 53 | { 54 | /** 55 | * The request quota limit set by the transcription service provider 56 | * has been exhausted. 57 | */ 58 | RESOURCES_EXHAUSTED 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockAccountID.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | 22 | import java.util.*; 23 | 24 | /** 25 | * Mock AccountID for testing purposes. 26 | * 27 | * @author Pawel Domas 28 | */ 29 | public class MockAccountID 30 | extends AccountID 31 | { 32 | /** 33 | * Creates an account id for the specified provider userid and 34 | * accountProperties. 35 | * If account uid exists in account properties, we are loading the account 36 | * and so load its value from there, prevent changing account uid 37 | * when server changed (serviceName has changed). 38 | * 39 | * @param userID a String that uniquely identifies the user. 40 | * @param accountProperties a Map containing any other protocol and 41 | * implementation specific account initialization properties 42 | * @param protocolName the name of the protocol implemented by the provider 43 | * that this id is meant for. 44 | */ 45 | public MockAccountID(String userID, 46 | Map accountProperties, 47 | String protocolName) 48 | { 49 | super(userID, accountProperties, protocolName, "mock"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/xmpp/CallControlAuthorizationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.xmpp; 19 | 20 | import org.jivesoftware.smack.packet.*; 21 | 22 | import java.util.*; 23 | 24 | import static org.jivesoftware.smack.packet.StanzaError.Condition.forbidden; 25 | 26 | /** 27 | * This exception is thrown when a request is not from a permitted entity. 28 | */ 29 | public class CallControlAuthorizationException 30 | extends Exception 31 | { 32 | private IQ iq; 33 | 34 | /** 35 | * Creates a new instance of this class. 36 | * 37 | * @param iq The IQ which failed the authorization check. 38 | */ 39 | public CallControlAuthorizationException(IQ iq) 40 | { 41 | Objects.requireNonNull(iq); 42 | this.iq = iq; 43 | } 44 | 45 | /** 46 | * Gets the IQ that failed the authorization check. 47 | * 48 | * @return the IQ that failed the authorization check. 49 | */ 50 | public IQ getIq() 51 | { 52 | return iq; 53 | } 54 | 55 | /** 56 | * Gets an error IQ based on the IQ that failed the validation with 57 | * a condition of 58 | * {@link org.jivesoftware.smack.packet.StanzaError.Condition#forbidden}. 59 | * 60 | * @return an error stanza. 61 | */ 62 | public IQ getErrorIq() 63 | { 64 | return IQ.createErrorResponse(iq, forbidden); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /debian/postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # postrm script for jigasi 3 | # 4 | # see: dh_installdeb(1) 5 | 6 | set -e 7 | 8 | # summary of how this script can be called: 9 | # * `remove' 10 | # * `purge' 11 | # * `upgrade' 12 | # * `failed-upgrade' 13 | # * `abort-install' 14 | # * `abort-install' 15 | # * `abort-upgrade' 16 | # * `disappear' 17 | # 18 | # for details, see http://www.debian.org/doc/debian-policy/ or 19 | # the debian-policy package 20 | 21 | # Load debconf 22 | . /usr/share/debconf/confmodule 23 | 24 | 25 | case "$1" in 26 | purge) 27 | 28 | # Clear the debconf variable 29 | db_purge 30 | 31 | # clear user and group 32 | # ensure nothing is running as jigasi user 33 | if ps -u jigasi h; then 34 | `ps -u jigasi -o pid h | xargs kill` 35 | fi 36 | # and then remove the user 37 | if getent passwd jigasi > /dev/null ; then 38 | deluser jigasi 39 | fi 40 | 41 | # debconf hostname question 42 | . /usr/share/debconf/confmodule 43 | db_get jitsi-videobridge/jvb-hostname 44 | JVB_HOSTNAME="$RET" 45 | PROSODY_HOST_CONFIG="/etc/prosody/conf.avail/$JVB_HOSTNAME.cfg.lua" 46 | if [ -f $PROSODY_HOST_CONFIG ]; then 47 | prosodyctl deluser jigasi@auth.$JVB_HOSTNAME < /dev/null || true 48 | fi 49 | 50 | rm -rf /usr/share/jigasi/ 51 | rm -f /etc/jitsi/jigasi/config 52 | rm -f /etc/jitsi/jigasi/sip-communicator.properties 53 | rm -f /etc/jitsi/jigasi/logging.properties 54 | 55 | ;; 56 | 57 | remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) 58 | ;; 59 | 60 | *) 61 | echo "postrm called with unknown argument \`$1'" >&2 62 | exit 1 63 | ;; 64 | esac 65 | 66 | # dh_installdeb will replace this with shell code automatically 67 | # generated by other debhelper scripts. 68 | 69 | #DEBHELPER# 70 | 71 | db_stop 72 | 73 | exit 0 74 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/rest/RESTUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2015 - present, 8x8 Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jitsi.jigasi.rest; 17 | 18 | import java.util.regex.*; 19 | 20 | /** 21 | * Class gathers utility methods HTTP and REST related. 22 | * 23 | * @author Pawel Domas 24 | */ 25 | public class RESTUtil 26 | { 27 | /** 28 | * The MIME type of HTTP content in JSON format. 29 | */ 30 | public static final String JSON_CONTENT_TYPE = "application/json"; 31 | 32 | /** 33 | * The MIME type of HTTP content in JSON format with a charset. 34 | */ 35 | public static final String JSON_CONTENT_TYPE_WITH_CHARSET 36 | = JSON_CONTENT_TYPE + ";charset=UTF-8"; 37 | 38 | /** 39 | * Pattern matcher used to detect JSON content type. 40 | */ 41 | private static final Pattern JsonContentTypeMatcher 42 | = Pattern.compile( 43 | "^\\s?application/json((\\s?)|(;\\s?(charset=UTF-8\\s?)?$))?"); 44 | 45 | /** 46 | * Determines whether a specific MIME type of HTTP content specifies a JSON 47 | * representation. 48 | * 49 | * @param contentType the MIME type of HTTP content to determine whether it 50 | * specifies a JSON representation 51 | * @return {@code true} if {@code contentType} stands for a MIME type of 52 | * HTTP content which specifies a JSON representation; otherwise, 53 | * {@code false} 54 | */ 55 | static public boolean isJSONContentType(String contentType) 56 | { 57 | return contentType != null && 58 | JsonContentTypeMatcher.matcher(contentType).matches(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockPeerMediaHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | import net.java.sip.communicator.service.protocol.media.*; 22 | import org.jitsi.service.neomedia.event.*; 23 | 24 | /** 25 | * @author Pawel Domas 26 | */ 27 | public class MockPeerMediaHandler 28 | extends CallPeerMediaHandler 29 | { 30 | /** 31 | * Creates a new handler that will be managing media streams for 32 | * peer. 33 | * 34 | * @param peer the CallPeer instance that we will be managing 35 | * media for. 36 | * @param srtpListener the object that receives SRTP security events. 37 | */ 38 | public MockPeerMediaHandler( 39 | MockCallPeer peer, 40 | SrtpListener srtpListener) 41 | { 42 | super(peer, srtpListener); 43 | } 44 | 45 | @Override 46 | protected TransportManager getTransportManager() 47 | { 48 | return null; 49 | } 50 | 51 | @Override 52 | protected TransportManager queryTransportManager() 53 | { 54 | return null; 55 | } 56 | 57 | @Override 58 | protected void throwOperationFailedException(String message, int errorCode, 59 | Throwable cause) 60 | throws OperationFailedException 61 | { 62 | throw new OperationFailedException(message, errorCode, cause); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/OutCallListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | import net.java.sip.communicator.service.protocol.event.*; 22 | 23 | /** 24 | * The purpose of this class is to encapsulate the process of waiting for 25 | * outgoing call get created on specified OperationSetBasicTelephony. 26 | * 27 | * @author Pawel Domas 28 | */ 29 | public class OutCallListener 30 | implements CallListener 31 | { 32 | private Call outgoingCall; 33 | 34 | private OperationSetBasicTelephony telephony; 35 | 36 | public void bind(OperationSetBasicTelephony telephony) 37 | { 38 | this.telephony = telephony; 39 | 40 | telephony.addCallListener(this); 41 | } 42 | 43 | public Call getOutgoingCall(long timeout) 44 | throws InterruptedException 45 | { 46 | synchronized (this) 47 | { 48 | if (outgoingCall == null) 49 | { 50 | this.wait(timeout); 51 | } 52 | return outgoingCall; 53 | } 54 | } 55 | 56 | @Override 57 | public void incomingCallReceived(CallEvent event){ } 58 | 59 | @Override 60 | public void outgoingCallCreated(CallEvent event) 61 | { 62 | telephony.removeCallListener(this); 63 | 64 | synchronized (this) 65 | { 66 | outgoingCall = event.getSourceCall(); 67 | 68 | this.notifyAll(); 69 | } 70 | } 71 | 72 | @Override 73 | public void callEnded(CallEvent event){ } 74 | } 75 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/CallStateListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import static org.junit.jupiter.api.Assertions.assertEquals; 21 | 22 | import net.java.sip.communicator.service.protocol.*; 23 | import net.java.sip.communicator.service.protocol.event.*; 24 | 25 | /** 26 | * Class used to encapsulate the process of waiting for some CallState 27 | * set on given Call instance. 28 | * 29 | * @author Pawel domas 30 | */ 31 | public class CallStateListener 32 | extends CallChangeAdapter 33 | { 34 | private CallState targetState; 35 | 36 | @Override 37 | public void callStateChanged(CallChangeEvent evt) 38 | { 39 | Call call = evt.getSourceCall(); 40 | if (targetState.equals(call.getCallState())) 41 | { 42 | synchronized (this) 43 | { 44 | this.notifyAll(); 45 | } 46 | } 47 | } 48 | 49 | public void waitForState(Call watchedCall, 50 | CallState targetState, 51 | long timeout) 52 | throws InterruptedException 53 | { 54 | this.targetState = targetState; 55 | 56 | // FIXME: we can miss call state anyway ?(but timeout will release) 57 | if (!targetState.equals(watchedCall.getCallState())) 58 | { 59 | synchronized (this) 60 | { 61 | watchedCall.addCallChangeListener(this); 62 | 63 | this.wait(timeout); 64 | } 65 | } 66 | 67 | watchedCall.removeCallChangeListener(this); 68 | 69 | assertEquals(targetState, watchedCall.getCallState()); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/GoogleCloudTranslationService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import com.google.cloud.translate.*; 21 | import com.google.cloud.translate.Translate.*; 22 | 23 | /** 24 | * Implements a {@link TranslationService} which will use Google Cloud 25 | * translate API to translate the given text from one language to another. 26 | * 27 | * Requires google cloud sdk on the machine running the JVM running 28 | * this application. See 29 | * https://cloud.google.com/translate/docs/quickstart 30 | * for details 31 | * 32 | * @author Praveen Kumar Gupta 33 | */ 34 | public class GoogleCloudTranslationService 35 | implements TranslationService 36 | { 37 | 38 | /** 39 | * The translation model to be used for translation. 40 | * Possible values are {@code base} and {@code nmt} 41 | */ 42 | private static final TranslateOption model = TranslateOption.model("nmt"); 43 | 44 | /** 45 | * Translation service object for accessing the cloud translate API. 46 | */ 47 | private static final Translate translator 48 | = TranslateOptions.getDefaultInstance().getService(); 49 | 50 | /** 51 | * {@inheritDoc} 52 | */ 53 | @Override 54 | public String translate(String sourceText, 55 | String sourceLang, String targetLang) 56 | { 57 | TranslateOption srcLang = TranslateOption.sourceLanguage(sourceLang); 58 | TranslateOption tgtLang = TranslateOption.targetLanguage(targetLang); 59 | 60 | Translation translation = translator.translate( 61 | sourceText, srcLang, tgtLang, model); 62 | 63 | return translation.getTranslatedText(); 64 | } 65 | } -------------------------------------------------------------------------------- /script/reconfigure_xmpp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -z "$DRY_RUN" ] && DRY_RUN="false" 4 | # path of file to parse for intended configuration 5 | [ -z "$CONFIG_PATH" ] && CONFIG_PATH="/etc/jitsi/jigasi/sip-communicator.properties" 6 | 7 | CC_MUC_BASE_URL="http://localhost:8788/configure/call-control-muc" 8 | CC_MUC_LIST_URL="$CC_MUC_BASE_URL/list" 9 | CC_MUC_ADD_URL="$CC_MUC_BASE_URL/add" 10 | CC_MUC_REMOVE_URL="$CC_MUC_BASE_URL/remove" 11 | 12 | CC_MUC_PREFIX="net.java.sip.communicator.impl.protocol.jabber" 13 | ESCAPE_PREFIX="${CC_MUC_PREFIX//\./\\.}" 14 | 15 | # get all server ids from the configuration files 16 | CONFIG_SERVER_IDS="$(grep "$CC_MUC_PREFIX.acc" $CONFIG_PATH \ 17 | | cut -d '.' -f 8 \ 18 | | grep '=' \ 19 | | cut -d '=' -f2)" 20 | 21 | [[ "$DRY_RUN" == "true" ]] && echo "Found Server IDs: $CONFIG_SERVER_IDS" 22 | 23 | # init processed server ids list 24 | SERVER_IDS="[]" 25 | for SERVER_ID in $CONFIG_SERVER_IDS; do 26 | SERVER_IDS="$(echo "[\"$SERVER_ID\"]" $SERVER_IDS | jq -s add)" 27 | # munge the properties file for this server into json 28 | CONFIG_JSON="$(grep "$CC_MUC_PREFIX.$SERVER_ID\." $CONFIG_PATH \ 29 | | grep -v '^#' \ 30 | | sed "s/$ESCAPE_PREFIX\.$SERVER_ID\./\"/g" \ 31 | | sed 's/=/":"/' \ 32 | | sed 's/$/",/')" 33 | # build the json for the configuration call 34 | echo "{$CONFIG_JSON\"id\":\"$SERVER_ID\"}" | jq '. + {"PASSWORD": .PASSWORD|@base64d}' > /tmp/cc-muc.json 35 | if [ "$DRY_RUN" == "true" ]; then 36 | echo "Would Add MUC: $SERVER_ID" 37 | cat /tmp/cc-muc.json | grep -v 'PASSWORD' | jq 38 | else 39 | echo "Adding MUC: $SERVER_ID" 40 | curl -s -H"Content-Type: application/json" -X POST -d @/tmp/cc-muc.json $CC_MUC_ADD_URL 41 | fi 42 | rm /tmp/cc-muc.json 43 | i=$((i+1)) 44 | done 45 | 46 | MUC_LIST=$(curl -s $CC_MUC_LIST_URL) 47 | # set empty list if no MUCs are found 48 | if [[ $? -gt 0 ]]; then 49 | echo "Failed to get muc list, setting to empty list" 50 | MUC_LIST="[]" 51 | fi 52 | 53 | CC_MUC_REMOVE_LIST=$(echo "$MUC_LIST" | jq -r ". - $SERVER_IDS | .[]") 54 | 55 | for MUC in $CC_MUC_REMOVE_LIST; do 56 | if [ "$DRY_RUN" == "true" ]; then 57 | echo "Would Remove MUC: $MUC" 58 | else 59 | echo "Removing MUC: $MUC" 60 | curl -s -H"Content-Type: application/json" -X POST -d "{\"id\":\"$MUC\"}" $CC_MUC_REMOVE_URL 61 | fi 62 | done 63 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscriptionAlternative.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | /** 21 | * An alternative transcription of a chunk of audio. 22 | * 23 | * @author Boris Grozev 24 | */ 25 | public class TranscriptionAlternative 26 | { 27 | /** 28 | * The default confidence value. 29 | */ 30 | private static double DEFAULT_CONFIDENCE = 1.0D; 31 | 32 | /** 33 | * The text of the transcription alternative. 34 | */ 35 | private String transcription; 36 | 37 | /** 38 | * The confidence level. 39 | */ 40 | private double confidence; 41 | 42 | /** 43 | * Initializes a new {@link TranscriptionAlternative} instance. 44 | * @param transcription the text of the transcription alternative. 45 | * @param confidence the confidence level. 46 | */ 47 | public TranscriptionAlternative(String transcription, double confidence) 48 | { 49 | this.transcription = transcription; 50 | this.confidence = confidence; 51 | } 52 | 53 | /** 54 | * Initializes a new {@link TranscriptionAlternative} instance with a 55 | * default confidence level. 56 | * @param transcription the text of the transcription alternative. 57 | */ 58 | public TranscriptionAlternative(String transcription) 59 | { 60 | this(transcription, DEFAULT_CONFIDENCE); 61 | } 62 | 63 | /** 64 | * @return the text of this transcription alternative. 65 | */ 66 | public String getTranscription() 67 | { 68 | return transcription; 69 | } 70 | 71 | /** 72 | * @return the confidence level of this transcription alternative. 73 | */ 74 | public double getConfidence() 75 | { 76 | return confidence; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockCall.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | import net.java.sip.communicator.service.protocol.event.*; 22 | import net.java.sip.communicator.service.protocol.media.*; 23 | 24 | /** 25 | * @author Pawel Domas 26 | */ 27 | public class MockCall 28 | extends MediaAwareCall 31 | { 32 | /** 33 | * Creates a new Call instance. 34 | * 35 | * @param telephony 36 | */ 37 | protected MockCall(MockBasicTeleOpSet telephony) 38 | { 39 | super(telephony); 40 | } 41 | 42 | @Override 43 | public boolean isConferenceFocus() 44 | { 45 | return false; 46 | } 47 | 48 | @Override 49 | public void addLocalUserSoundLevelListener(SoundLevelListener l) 50 | { 51 | 52 | } 53 | 54 | @Override 55 | public void removeLocalUserSoundLevelListener(SoundLevelListener l) 56 | { 57 | 58 | } 59 | 60 | public void addCallPeer(MockCallPeer peer) 61 | { 62 | doAddCallPeer(peer); 63 | } 64 | 65 | public synchronized void hangup() 66 | { 67 | setCallState(CallState.CALL_ENDED); 68 | 69 | for (MockCallPeer peer : getCallPeerList()) 70 | { 71 | peer.setState(CallPeerState.DISCONNECTED); 72 | } 73 | } 74 | 75 | @Override 76 | public String toString() 77 | { 78 | return super.toString() + " " + getProtocolProvider().getProtocolName(); 79 | } 80 | 81 | public void setCallState(CallState newState) 82 | { 83 | super.setCallState(newState); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/rest/TranscriptServerBundleActivator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.rest; 19 | 20 | import org.eclipse.jetty.server.*; 21 | import org.eclipse.jetty.server.handler.*; 22 | import org.jitsi.jigasi.transcription.*; 23 | import org.osgi.framework.*; 24 | 25 | /** 26 | * Activate a jetty instance which is able to serve 27 | * {@link org.jitsi.jigasi.transcription.Transcript} which are locally stored 28 | * with a {@link org.jitsi.jigasi.transcription.LocalTxtTranscriptHandler} or 29 | * {@link org.jitsi.jigasi.transcription.LocalJsonTranscriptHandler} 30 | * 31 | * @author Nik Vaessen 32 | */ 33 | public class TranscriptServerBundleActivator 34 | extends AbstractJettyBundleActivator 35 | { 36 | /** 37 | * The prefix of the property names for the Jetty instance managed by 38 | * this {@link AbstractJettyBundleActivator}. 39 | */ 40 | public static final String JETTY_PROPERTY_PREFIX 41 | = "org.jitsi.jigasi.transcription"; 42 | 43 | /** 44 | * Create a new Bundle which serves locally stored 45 | * {@link org.jitsi.jigasi.transcription.Transcript}s formatted by a 46 | * {@link org.jitsi.jigasi.transcription.TranscriptPublisher} 47 | */ 48 | public TranscriptServerBundleActivator() 49 | { 50 | super(JETTY_PROPERTY_PREFIX, JETTY_PROPERTY_PREFIX); 51 | } 52 | 53 | /** 54 | * {@inheritDoc} 55 | */ 56 | @Override 57 | protected Handler initializeHandlerList(BundleContext bundleContext, 58 | Server server) 59 | { 60 | ResourceHandler fileHandler = new ResourceHandler(); 61 | 62 | fileHandler.setDirectoriesListed(false); 63 | fileHandler.setResourceBase( 64 | AbstractTranscriptPublisher.getLogDirPath()); 65 | 66 | return fileHandler; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/sounds/SoundRateLimiter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.sounds; 19 | 20 | import java.time.*; 21 | import java.util.concurrent.atomic.*; 22 | 23 | /** 24 | * Implements RateLimiter for sound notifications. 25 | */ 26 | class SoundRateLimiter 27 | { 28 | /** 29 | * Initial time point. 30 | */ 31 | private final AtomicReference startTimePoint = new AtomicReference<>(null); 32 | 33 | /** 34 | * Timeout in milliseconds. 35 | */ 36 | private long limiterTimeout; 37 | 38 | /** 39 | * SoundRateLimiter constructor. 40 | * 41 | * @param maxTimeout Timeout in milliseconds to block notification. 42 | */ 43 | SoundRateLimiter(long maxTimeout) 44 | { 45 | this.limiterTimeout = maxTimeout; 46 | } 47 | 48 | /** 49 | * Checks if timeout since last notification has passed. 50 | * When it returns false, sound notification can be played. 51 | * 52 | * @return true of enabled, false otherwise. 53 | */ 54 | public boolean on() 55 | { 56 | if (this.startTimePoint.compareAndSet(null, Instant.now())) 57 | { 58 | return false; 59 | } 60 | 61 | Instant prevTimePoint = this.startTimePoint.get(); 62 | 63 | if (prevTimePoint == null) 64 | { 65 | return false; 66 | } 67 | 68 | long elapsedMs = 69 | Instant.now().toEpochMilli() 70 | - prevTimePoint.toEpochMilli(); 71 | 72 | if (elapsedMs >= this.limiterTimeout) 73 | { 74 | this.startTimePoint.set(Instant.now()); 75 | return false; 76 | } 77 | 78 | return true; 79 | } 80 | 81 | /** 82 | * {@inheritDoc} 83 | */ 84 | public void reset() 85 | { 86 | this.startTimePoint.set(null); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.utils.logging.*; 21 | import org.json.simple.*; 22 | 23 | import java.io.*; 24 | import java.net.*; 25 | import java.nio.charset.*; 26 | 27 | /** 28 | * Utility functions used in the transcription package. 29 | * 30 | * @author Damian Minkov 31 | */ 32 | public class Util 33 | { 34 | /** 35 | * The logger for this class 36 | */ 37 | private final static Logger logger = Logger.getLogger(Util.class); 38 | 39 | /** 40 | * Posts json object to an address of a service to handle it and further 41 | * process it. 42 | * @param address the address where to send the post request. 43 | * @param json the json object to send. 44 | */ 45 | public static void postJSON(String address, JSONObject json) 46 | { 47 | try 48 | { 49 | URL url = new URL(address); 50 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 51 | conn.setDoOutput(true); 52 | conn.setRequestMethod("POST"); 53 | conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); 54 | 55 | OutputStream os = conn.getOutputStream(); 56 | os.write(json.toString().getBytes(StandardCharsets.UTF_8)); 57 | os.flush(); 58 | 59 | if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) 60 | { 61 | logger.error("Error for action post received: " 62 | + conn.getResponseCode() 63 | + "(" + conn.getResponseMessage() + ")"); 64 | } 65 | 66 | conn.disconnect(); 67 | } 68 | catch (IOException e) 69 | { 70 | logger.error("Error posting transcription", e); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/rest/MetricsHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2024 - present, 8x8 Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jitsi.jigasi.rest; 17 | 18 | import io.prometheus.client.exporter.common.*; 19 | import jakarta.servlet.*; 20 | import jakarta.servlet.http.*; 21 | import org.eclipse.jetty.server.*; 22 | import org.eclipse.jetty.server.handler.*; 23 | import org.jitsi.jigasi.metrics.*; 24 | import org.jitsi.jigasi.stats.*; 25 | 26 | import java.io.*; 27 | 28 | public class MetricsHandler extends AbstractHandler 29 | { 30 | @Override 31 | public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) 32 | throws IOException, ServletException 33 | { 34 | if ("/metrics".equals(target)) 35 | { 36 | String accept = request.getHeader("Accept"); 37 | 38 | Statistics.updateMetrics(); 39 | 40 | String responseBody; 41 | if (accept != null && accept.startsWith("application/openmetrics-text")) 42 | { 43 | responseBody = JigasiMetricsContainer.INSTANCE.getPrometheusMetrics( 44 | TextFormat.CONTENT_TYPE_OPENMETRICS_100); 45 | response.setContentType(TextFormat.CONTENT_TYPE_OPENMETRICS_100); 46 | } 47 | else if (accept != null && accept.startsWith("text/plain")) 48 | { 49 | responseBody = JigasiMetricsContainer.INSTANCE.getPrometheusMetrics(TextFormat.CONTENT_TYPE_004); 50 | response.setContentType(TextFormat.CONTENT_TYPE_004); 51 | } 52 | else 53 | { 54 | responseBody = JigasiMetricsContainer.INSTANCE.getJsonString(); 55 | response.setContentType(RESTUtil.JSON_CONTENT_TYPE_WITH_CHARSET); 56 | } 57 | 58 | Writer writer = response.getWriter(); 59 | writer.write(responseBody); 60 | response.setStatus(200); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /debian/init.d: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # INIT script for Jitsi Gateway for SIP 4 | # Version: 1.0 01-Aug-2014 yasen@bluejimp.com 5 | # 6 | ### BEGIN INIT INFO 7 | # Provides: jigasi 8 | # Required-Start: $local_fs 9 | # Required-Stop: $local_fs 10 | # Default-Start: 2 3 4 5 11 | # Default-Stop: 0 1 6 12 | # Short-Description: Jitsi Gateway for SIP 13 | # Description: Gateway for Jitsi Meet to SIP 14 | ### END INIT INFO 15 | 16 | . /lib/lsb/init-functions 17 | 18 | # Include jigasi defaults if available 19 | if [ -f /etc/jitsi/jigasi/config ]; then 20 | . /etc/jitsi/jigasi/config 21 | fi 22 | 23 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 24 | DAEMON=/usr/share/jigasi/jigasi.sh 25 | DAEMON_DIR=/usr/share/jigasi/ 26 | NAME=jigasi 27 | USER=jigasi 28 | PIDFILE=/var/run/jigasi.pid 29 | LOGDIR=/var/log/jitsi 30 | LOGFILE=$LOGDIR/jigasi.log 31 | DESC=jigasi 32 | DAEMON_OPTS=" --host=$JIGASI_HOST --domain=$JIGASI_HOSTNAME --logdir=$LOGDIR --configdir=/etc/jitsi --configdirname=jigasi $JIGASI_OPTS" 33 | 34 | if [ ! -x $DAEMON ] ;then 35 | echo "Daemon not executable: $DAEMON" 36 | exit 1 37 | fi 38 | 39 | set -e 40 | 41 | stop() { 42 | if [ -f $PIDFILE ]; then 43 | PID=$(cat $PIDFILE) 44 | fi 45 | echo -n "Stopping $DESC: " 46 | if [ $PID ]; then 47 | kill $PID || true 48 | rm $PIDFILE || true 49 | echo "$NAME stopped." 50 | else 51 | echo "$NAME doesn't seem to be running." 52 | fi 53 | } 54 | start() { 55 | if [ -f $PIDFILE ]; then 56 | echo "$DESC seems to be already running, we found pidfile $PIDFILE." 57 | exit 1 58 | fi 59 | echo -n "Starting $DESC: " 60 | 61 | start-stop-daemon --start --quiet --background --chuid $USER --make-pidfile --pidfile $PIDFILE \ 62 | --exec /bin/bash -- -c "JAVA_SYS_PROPS=\"$JAVA_SYS_PROPS\" exec $DAEMON $DAEMON_OPTS > $LOGFILE 2>&1" 63 | 64 | echo "$NAME started." 65 | } 66 | 67 | reload() { 68 | echo 'Not yet implemented.' 69 | } 70 | 71 | status() { 72 | status_of_proc -p $PIDFILE java "$NAME" && exit 0 || exit $? 73 | } 74 | 75 | case "$1" in 76 | start) 77 | start 78 | ;; 79 | stop) 80 | stop 81 | ;; 82 | restart) 83 | stop 84 | start 85 | ;; 86 | reload) 87 | reload 88 | ;; 89 | status) 90 | status 91 | ;; 92 | *) 93 | N=/etc/init.d/$NAME 94 | echo "Usage: $N {start|stop|restart|reload|status}" >&2 95 | exit 1 96 | ;; 97 | esac 98 | 99 | exit 0 100 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/rest/RESTBundleActivator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.rest; 19 | 20 | import org.eclipse.jetty.server.*; 21 | import org.osgi.framework.*; 22 | 23 | /** 24 | * Implements BundleActivator for the OSGi bundle which implements a 25 | * REST API for Jigasi. 26 | *

27 | * The REST API of Jigasi is currently served over HTTP on port 28 | * 8788 by default. The default port value may be overridden by the 29 | * System and ConfigurationService property with name 30 | * org.jitsi.jigasi.rest.jetty.port. 31 | *

32 | * 33 | * @author Damian Minkov 34 | */ 35 | public class RESTBundleActivator 36 | extends AbstractJettyBundleActivator 37 | { 38 | /** 39 | * The REST-like HTTP/JSON API of Jigasi. 40 | */ 41 | public static final String REST_API = "rest"; 42 | 43 | /** 44 | * The (base) System and/or ConfigurationService property 45 | * of the REST-like HTTP/JSON API of Jigasi. 46 | */ 47 | public static final String REST_API_PNAME 48 | = "org.jitsi.jigasi." + REST_API; 49 | 50 | /** 51 | * The name of the System and ConfigurationService 52 | * boolean property which enables graceful shutdown through REST API. 53 | * It is disabled by default. 54 | */ 55 | private static final String ENABLE_REST_SHUTDOWN_PNAME 56 | = "org.jitsi.jigasi.ENABLE_REST_SHUTDOWN"; 57 | 58 | /** 59 | * Initializes a new {@code RESTBundleActivator} instance. 60 | */ 61 | public RESTBundleActivator() 62 | { 63 | super(REST_API_PNAME, REST_API_PNAME); 64 | } 65 | 66 | /** 67 | * {@inheritDoc} 68 | */ 69 | @Override 70 | protected Handler initializeHandlerList(BundleContext bundleContext, 71 | Server server) 72 | { 73 | return new HandlerImpl(bundleContext, 74 | getConfigService().getBoolean(ENABLE_REST_SHUTDOWN_PNAME, false)); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/action/ActionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription.action; 19 | 20 | /** 21 | * Action handler. Initialized with a name, phrase to detect and url address to 22 | * use for sending detected result when a command is detected. 23 | * 24 | * @author Damian Minkov 25 | */ 26 | public class ActionHandler 27 | { 28 | /** 29 | * The name of the handler, used only internally (logging). 30 | */ 31 | private String name; 32 | 33 | /** 34 | * The phrase to detect. 35 | */ 36 | private String phrase; 37 | 38 | /** 39 | * The url address to use for sending commands. 40 | */ 41 | private String url; 42 | 43 | /** 44 | * Constructs new ActionHandler. 45 | * @param name the name. 46 | * @param phrase the phrase to expect. 47 | * @param url the address to post the result. 48 | */ 49 | public ActionHandler(String name, String phrase, String url) 50 | { 51 | this.name = name; 52 | this.phrase = phrase; 53 | this.url = url; 54 | } 55 | 56 | /** 57 | * The phrase to detect. 58 | * @return the phrase to detect. 59 | */ 60 | public String getPhrase() 61 | { 62 | return this.phrase; 63 | } 64 | 65 | /** 66 | * The url address to use for sending commands. 67 | * @return the url address to use for sending commands. 68 | */ 69 | public String getUrl() 70 | { 71 | return url; 72 | } 73 | 74 | /** 75 | * The name of the handler, used only internally (logging). 76 | * @return the name of the handler. 77 | */ 78 | public String getName() 79 | { 80 | return name; 81 | } 82 | 83 | @Override 84 | public String toString() 85 | { 86 | return "ActionHandler{" + 87 | "name='" + name + '\'' + 88 | ", phrase='" + phrase + '\'' + 89 | ", url='" + url + '\'' + 90 | '}'; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockProtocolProviderFactoriesActivator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | 22 | import org.osgi.framework.*; 23 | 24 | import java.util.*; 25 | 26 | /** 27 | * Registers mock protocol provider factories for SIP and XMPP. 28 | * 29 | * @author Pawel Domas 30 | */ 31 | public class MockProtocolProviderFactoriesActivator 32 | implements BundleActivator 33 | { 34 | private ServiceRegistration xmppRegistration; 35 | 36 | private ServiceRegistration sipRegistration; 37 | 38 | @Override 39 | public void start(BundleContext bundleContext) 40 | { 41 | MockProtocolProviderFactory sipFactory 42 | = new MockProtocolProviderFactory( 43 | bundleContext, ProtocolNames.SIP); 44 | 45 | MockProtocolProviderFactory xmppFactory 46 | = new MockProtocolProviderFactory( 47 | bundleContext, ProtocolNames.JABBER); 48 | 49 | Hashtable hashtable = new Hashtable(); 50 | 51 | // Register XMPP 52 | hashtable.put(ProtocolProviderFactory.PROTOCOL, ProtocolNames.JABBER); 53 | 54 | xmppRegistration = bundleContext.registerService( 55 | ProtocolProviderFactory.class.getName(), 56 | xmppFactory, 57 | hashtable); 58 | 59 | // Register SIP 60 | hashtable.put(ProtocolProviderFactory.PROTOCOL, ProtocolNames.SIP); 61 | 62 | sipRegistration = bundleContext.registerService( 63 | ProtocolProviderFactory.class.getName(), 64 | sipFactory, 65 | hashtable); 66 | } 67 | 68 | @Override 69 | public void stop(BundleContext bundleContext) 70 | { 71 | if (xmppRegistration != null) 72 | xmppRegistration.unregister(); 73 | 74 | if (sipRegistration != null) 75 | sipRegistration.unregister(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/visitor/StompUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.visitor; 19 | 20 | import java.nio.*; 21 | 22 | /** 23 | * The utils for sending/receiving STOMP messages. 24 | */ 25 | public class StompUtils 26 | { 27 | final static String NEW_LINE = "\n"; 28 | final static String END = "\u0000"; 29 | final static String EMPTY_LINE = ""; 30 | final static String DELIMITER = ":"; 31 | final static ByteBuffer PING_BODY = ByteBuffer.wrap(new byte[] {'\n'}); 32 | 33 | private static String buildHeader(String key, String value) 34 | { 35 | if (value != null) 36 | { 37 | return key + ':' + value + NEW_LINE; 38 | } 39 | else 40 | { 41 | return key + NEW_LINE; 42 | } 43 | } 44 | 45 | /** 46 | * Builds the connect message to send. 47 | * @param token The token to authenticate. 48 | * @param heartbeatOutgoing The ms to send for outgoing heartbeat interval. 49 | * @param heartbeatIncoming The ms to send for incoming heartbeat interval. 50 | * @return The message. 51 | */ 52 | static String buildConnectMessage(String token, long heartbeatOutgoing, long heartbeatIncoming) 53 | { 54 | String headers = buildHeader("CONNECT", null); 55 | headers += buildHeader("accept-version", "1.2,1.1,1.0"); 56 | headers += buildHeader("heart-beat", heartbeatOutgoing + "," + heartbeatIncoming); 57 | headers += buildHeader("Authorization", "Bearer " + token); 58 | 59 | return headers + NEW_LINE + END; 60 | } 61 | 62 | /** 63 | * Builds a subscribe message. 64 | * @param topic The topic to subscribe to. 65 | * @return The message. 66 | */ 67 | static String buildSubscribeMessage(String topic) 68 | { 69 | String headers = buildHeader("SUBSCRIBE", null); 70 | headers += buildHeader("destination", topic); 71 | headers += buildHeader("id", "1"); // this is the first and only message we send 72 | 73 | return headers + NEW_LINE + END; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/muc/MockRoomMember.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock.muc; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | 22 | /** 23 | * @author Pawel Domas 24 | */ 25 | public class MockRoomMember 26 | implements ChatRoomMember 27 | { 28 | private final String name; 29 | 30 | private final MockMultiUserChat room; 31 | 32 | private ChatRoomMemberRole role = ChatRoomMemberRole.MEMBER; 33 | 34 | public MockRoomMember(String name, MockMultiUserChat chatRoom) 35 | { 36 | this.name = name; 37 | this.room = chatRoom; 38 | } 39 | 40 | @Override 41 | public ChatRoom getChatRoom() 42 | { 43 | return room; 44 | } 45 | 46 | @Override 47 | public ProtocolProviderService getProtocolProvider() 48 | { 49 | return room.getParentProvider(); 50 | } 51 | 52 | @Override 53 | public String getContactAddress() 54 | { 55 | return name; 56 | } 57 | 58 | @Override 59 | public String getName() 60 | { 61 | return name; 62 | } 63 | 64 | @Override 65 | public byte[] getAvatar() 66 | { 67 | return new byte[0]; 68 | } 69 | 70 | @Override 71 | public Contact getContact() 72 | { 73 | return null; 74 | } 75 | 76 | @Override 77 | public ChatRoomMemberRole getRole() 78 | { 79 | return role; 80 | } 81 | 82 | @Override 83 | public void setRole(ChatRoomMemberRole role) 84 | { 85 | this.role = role; 86 | } 87 | 88 | @Override 89 | public String getDisplayName() 90 | { 91 | return null; 92 | } 93 | 94 | @Override 95 | public PresenceStatus getPresenceStatus() 96 | { 97 | return null; 98 | } 99 | 100 | @Override 101 | public String toString() 102 | { 103 | return "Member@" + hashCode() + "[" + name + "]"; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/cmd/CmdLineArgsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2015 - present, 8x8 Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jitsi.jigasi.cmd; 17 | 18 | import static org.junit.jupiter.api.Assertions.*; 19 | 20 | import org.junit.jupiter.api.*; 21 | 22 | public class CmdLineArgsTest 23 | { 24 | /** 25 | * A basic test for {@link CmdLine} class. 26 | */ 27 | @Test 28 | public void testJvbArgs() 29 | throws ParseException 30 | { 31 | String[] args = { 32 | "--apis=xmpp,rest", 33 | "-blablaarg=", 34 | "--domain=example.com", 35 | "-max-port=21000", 36 | "secret=secretpass", 37 | "--port=5275", 38 | "somegarbagearg", 39 | "-=dsf=" 40 | }; 41 | 42 | // create the parser 43 | CmdLine parser = new CmdLine(); 44 | 45 | // parse the command line arguments 46 | parser.parse(args); 47 | 48 | assertEquals("example.com", parser.getOptionValue("domain")); 49 | assertEquals(21000, parser.getIntOptionValue("max-port", 1)); 50 | assertEquals("secretpass", parser.getOptionValue("secret")); 51 | assertEquals(5275, parser.getIntOptionValue("port", 1)); 52 | assertEquals("xmpp,rest", parser.getOptionValue("apis")); 53 | 54 | // Default value 55 | assertEquals( 56 | "localhost", parser.getOptionValue("host", "localhost")); 57 | 58 | // Parsed default value 59 | assertEquals(10000, parser.getIntOptionValue("min-port", 10000)); 60 | } 61 | 62 | @Test 63 | public void testRequiredArg() 64 | { 65 | String[] args = { "--min-port=23423" }; 66 | 67 | CmdLine parser = new CmdLine(); 68 | 69 | parser.addRequiredArgument("-max-port"); 70 | parser.addRequiredArgument("min-port"); 71 | 72 | try 73 | { 74 | parser.parse(args); 75 | 76 | fail("Missed required argument"); 77 | } 78 | catch (ParseException e) 79 | { 80 | assertEquals( 81 | "Some of required arguments were not specified: [max-port]", 82 | e.getMessage()); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/ServerSecurityAuthority.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | import org.apache.commons.lang3.*; 22 | import org.jitsi.utils.logging.*; 23 | 24 | /** 25 | * No UI just returns default credentials. 26 | * 27 | * @author Pawel Domas 28 | * @author George Politis 29 | */ 30 | public class ServerSecurityAuthority 31 | implements SecurityAuthority 32 | { 33 | /** 34 | * The logger. 35 | */ 36 | private final static Logger logger 37 | = Logger.getLogger(ServerSecurityAuthority.class); 38 | 39 | /** 40 | * The password to return. 41 | */ 42 | private final String password; 43 | 44 | private final ProtocolProviderService provider; 45 | 46 | public ServerSecurityAuthority( 47 | ProtocolProviderService provider, String password) 48 | { 49 | this.password = password; 50 | this.provider = provider; 51 | } 52 | 53 | @Override 54 | public UserCredentials obtainCredentials(String realm, 55 | UserCredentials defaultValues, 56 | int reasonCode) 57 | { 58 | if (reasonCode == WRONG_PASSWORD 59 | || reasonCode == WRONG_USERNAME) 60 | { 61 | logger.error( 62 | "Wrong username or password for provider:" + this.provider); 63 | return null; 64 | } 65 | 66 | if (StringUtils.isNotEmpty(StringUtils.trim(password))) 67 | { 68 | defaultValues.setPassword(password.toCharArray()); 69 | } 70 | 71 | return defaultValues; 72 | } 73 | 74 | @Override 75 | public UserCredentials obtainCredentials(String realm, 76 | UserCredentials defaultValues) 77 | { 78 | return defaultValues; 79 | } 80 | 81 | @Override 82 | public void setUserNameEditable(boolean isUserNameEditable) 83 | { 84 | 85 | } 86 | 87 | @Override 88 | public boolean isUserNameEditable() 89 | { 90 | return false; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscriptPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.service.neomedia.device.*; 21 | 22 | /** 23 | * This interface is used to save a transcript to a desired location 24 | * 25 | * @author Nik Vaessen 26 | */ 27 | public interface TranscriptPublisher 28 | { 29 | /** 30 | * Get a {@link Promise} which will be able to provide a description 31 | * and accept a {@link Transcript} to publish 32 | * 33 | * @return the {@link Promise} 34 | */ 35 | Promise getPublishPromise(); 36 | 37 | /** 38 | * A promise will be able to give a description of where or how the 39 | * {@link Transcript} will be published before it is actually published 40 | */ 41 | interface Promise 42 | { 43 | /** 44 | * Whether a description is available 45 | * 46 | * @return true if there is description, false otherwise 47 | */ 48 | boolean hasDescription(); 49 | 50 | /** 51 | * Get the description of how the transcript will be published once 52 | * this {@link Promise#publish(Transcript)} method has been called. 53 | * 54 | * @return the description as a String, which will be empty when 55 | * {@link this#hasDescription()} is false 56 | */ 57 | String getDescription(); 58 | 59 | /** 60 | * Publish the given {@link Transcript} to the desired location. 61 | * Can only be called once. 62 | * 63 | * @param transcript the transcript to publish 64 | */ 65 | void publish(Transcript transcript); 66 | 67 | /** 68 | * Give the {@link MediaDevice} 69 | * which is required to record the audio with a 70 | * {@link org.jitsi.service.neomedia.recording.Recorder} object. 71 | * If recording is desired, calling this method will start the 72 | * recording, otherwise it will do nothing. 73 | * 74 | * @param device the MediaDevice which will be used to 75 | * record the audio 76 | */ 77 | void maybeStartRecording(MediaDevice device); 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranslationResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | /** 21 | * A TranslationResult created after translating a {@link TranscriptionResult} 22 | * using a {@link TranslationService}. 23 | * 24 | * @author Praveen Kumar Gupta 25 | */ 26 | public class TranslationResult 27 | { 28 | 29 | /** 30 | * The language tag of this result's text. 31 | */ 32 | private String language; 33 | 34 | /** 35 | * The translated final transcript message in the given language. 36 | */ 37 | private String text; 38 | 39 | /** 40 | * {@link TranscriptionResult} whose translation in a particular language 41 | * is represented by this {@link TranslationResult} object. 42 | */ 43 | private TranscriptionResult transcriptionResult; 44 | 45 | /** 46 | * Initializes a {@link TranslationResult} object with the participant, 47 | * messageID and translated text, language. 48 | * 49 | * @param result the {@link TranscriptionResult} for this translation. 50 | * @param lang the target language for translation. 51 | * @param translation the translated text in the target language. 52 | */ 53 | public TranslationResult(TranscriptionResult result, 54 | String lang, 55 | String translation) 56 | { 57 | transcriptionResult = result; 58 | language = lang; 59 | text = translation; 60 | } 61 | 62 | /** 63 | * Get the language tag of this {@link TranslationResult}. 64 | * 65 | * @return the language tag as a String 66 | */ 67 | public String getLanguage() 68 | { 69 | return language; 70 | } 71 | 72 | /** 73 | * Get the translated text. 74 | * 75 | * @return the translated text. 76 | */ 77 | public String getTranslatedText() 78 | { 79 | return text; 80 | } 81 | 82 | /** 83 | * Get the {@link TranscriptionResult} whose translation is represented 84 | * by this object. 85 | * 86 | * @return transcriptionResult 87 | */ 88 | public TranscriptionResult getTranscriptionResult() 89 | { 90 | return transcriptionResult; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/SsrcRewriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import org.jitsi.impl.neomedia.*; 21 | import org.jitsi.impl.neomedia.transform.*; 22 | import org.jitsi.service.neomedia.*; 23 | 24 | /** 25 | * Transformer that will rewrite rtp packets ssrc, when attached to a stream. 26 | * 27 | * @author Damian Minkov 28 | */ 29 | public class SsrcRewriter 30 | extends SinglePacketTransformerAdapter 31 | implements TransformEngine 32 | { 33 | private final RTCPTransformer rtcpTransformer = new RTCPTransformer(); 34 | 35 | private final long ssrc; 36 | 37 | /** 38 | * Initializes a new {@link SsrcRewriter} instance. 39 | */ 40 | public SsrcRewriter(long ssrc) 41 | { 42 | super(RTPPacketPredicate.INSTANCE); 43 | this.ssrc = ssrc; 44 | } 45 | 46 | /** 47 | * Do the rewriting. 48 | * @param pkt 49 | * @return 50 | */ 51 | @Override 52 | public RawPacket transform(RawPacket pkt) 53 | { 54 | if (pkt.getLength() >= 12) 55 | pkt.setSSRC((int)this.ssrc); 56 | return pkt; 57 | } 58 | 59 | /** 60 | * Implements {@link TransformEngine#getRTPTransformer()}. 61 | */ 62 | @Override 63 | public PacketTransformer getRTPTransformer() 64 | { 65 | return this; 66 | } 67 | 68 | /** 69 | * Implements {@link TransformEngine#getRTCPTransformer()}. 70 | * 71 | * This TransformEngine does not transform RTCP packets. 72 | * 73 | */ 74 | @Override 75 | public PacketTransformer getRTCPTransformer() 76 | { 77 | return rtcpTransformer; 78 | } 79 | 80 | /** 81 | * Rewrites rtcp ssrc. 82 | */ 83 | public class RTCPTransformer 84 | extends SinglePacketTransformerAdapter 85 | { 86 | RTCPTransformer() 87 | { 88 | super(RTCPPacketPredicate.INSTANCE); 89 | } 90 | 91 | @Override 92 | public RawPacket transform(RawPacket pkt) 93 | { 94 | if (pkt.getLength() >= 8) 95 | pkt.writeInt(4, (int)SsrcRewriter.this.ssrc); 96 | return pkt; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/rest/RESTUtilTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2015 - present, 8x8 Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jitsi.jigasi.rest; 17 | 18 | import org.junit.jupiter.api.*; 19 | 20 | import static org.junit.jupiter.api.Assertions.*; 21 | 22 | /** 23 | * Some test for JSON pattern matcher. 24 | * 25 | * @author Pawel Domas 26 | */ 27 | public class RESTUtilTests 28 | { 29 | @Test 30 | public void testJSONContentMatcher() 31 | { 32 | assertFalse( 33 | RESTUtil.isJSONContentType("")); 34 | assertFalse( 35 | RESTUtil.isJSONContentType(null)); 36 | 37 | assertTrue( 38 | RESTUtil.isJSONContentType( 39 | RESTUtil.JSON_CONTENT_TYPE)); 40 | 41 | assertTrue( 42 | RESTUtil.isJSONContentType( 43 | RESTUtil.JSON_CONTENT_TYPE_WITH_CHARSET)); 44 | 45 | assertTrue( 46 | RESTUtil.isJSONContentType( 47 | "application/json")); 48 | 49 | assertTrue( 50 | RESTUtil.isJSONContentType( 51 | " application/json")); 52 | 53 | assertTrue( 54 | RESTUtil.isJSONContentType( 55 | "application/json ")); 56 | 57 | assertFalse( 58 | RESTUtil.isJSONContentType( 59 | "bapplication/json")); 60 | 61 | assertFalse( 62 | RESTUtil.isJSONContentType( 63 | "application/jsonx")); 64 | 65 | assertTrue( 66 | RESTUtil.isJSONContentType( 67 | "application/json;")); 68 | 69 | assertTrue( 70 | RESTUtil.isJSONContentType( 71 | " application/json;")); 72 | 73 | assertTrue( 74 | RESTUtil.isJSONContentType( 75 | "application/json; ")); 76 | 77 | assertTrue( 78 | RESTUtil.isJSONContentType( 79 | "application/json; ")); 80 | 81 | assertTrue( 82 | RESTUtil.isJSONContentType( 83 | "application/json;charset=UTF-8")); 84 | 85 | assertTrue( 86 | RESTUtil.isJSONContentType( 87 | "application/json; charset=UTF-8")); 88 | 89 | assertTrue( 90 | RESTUtil.isJSONContentType( 91 | "application/json; charset=UTF-8 ")); 92 | 93 | assertFalse( 94 | RESTUtil.isJSONContentType( 95 | "application/json; charset=UTF-88")); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/version/CurrentVersionImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2019 - present, 8x8 Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jitsi.jigasi.version; 17 | 18 | import org.jitsi.utils.version.*; 19 | 20 | import java.util.regex.*; 21 | 22 | /** 23 | * Keeps constants for the application version. 24 | * 25 | * Note that the constants are modified at build time, so changes to this file 26 | * must be synchronized with the build system. 27 | * 28 | * @author Boris Grozev 29 | */ 30 | public class CurrentVersionImpl 31 | { 32 | /** 33 | * Default version values can be overwritten by the manifest Implementation 34 | * Version in the format 2.1-build-id. 35 | */ 36 | private static int parsedMajor = 1; 37 | private static int parsedMinor = 1; 38 | private static String parsedBuildId = null; 39 | 40 | static { 41 | String version = CurrentVersionImpl.class.getPackage() 42 | .getImplementationVersion(); 43 | if (version != null) 44 | { 45 | Matcher m 46 | = Pattern.compile("(\\d*)\\.(\\d*)-(.*)").matcher(version); 47 | if (m.find()) 48 | { 49 | try 50 | { 51 | parsedMajor = Integer.parseInt(m.group(1)); 52 | } 53 | catch (NumberFormatException nfe) {} 54 | 55 | try 56 | { 57 | parsedMinor = Integer.parseInt(m.group(2)); 58 | } 59 | catch (NumberFormatException nfe) {} 60 | 61 | parsedBuildId = m.group(3); 62 | } 63 | } 64 | } 65 | 66 | /** 67 | * The major version. 68 | */ 69 | public static final int VERSION_MAJOR = parsedMajor; 70 | 71 | /** 72 | * The minor version. 73 | */ 74 | public static final int VERSION_MINOR = parsedMinor; 75 | 76 | /** 77 | * The version prerelease ID of the current application version. 78 | */ 79 | public static final String PRE_RELEASE_ID = null; 80 | 81 | /** 82 | * The nightly build ID. This file is auto-updated on compile time. 83 | */ 84 | public static final String NIGHTLY_BUILD_ID 85 | = parsedBuildId != null ? parsedBuildId : "build.git"; 86 | 87 | public static final Version VERSION 88 | = new VersionImpl( 89 | "Jigasi", 90 | VERSION_MAJOR, 91 | VERSION_MINOR, 92 | NIGHTLY_BUILD_ID, 93 | PRE_RELEASE_ID); 94 | } 95 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/CallPeerStateListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import static org.junit.jupiter.api.Assertions.assertEquals; 21 | 22 | import net.java.sip.communicator.service.protocol.*; 23 | import net.java.sip.communicator.service.protocol.event.*; 24 | 25 | import java.util.*; 26 | 27 | /** 28 | * Class used to wait for and assert specified {@link CallPeerState} on 29 | * selected call peer. 30 | * 31 | * @author Pawel Domas 32 | */ 33 | public class CallPeerStateListener 34 | extends CallPeerAdapter 35 | { 36 | private CallPeerState targetState; 37 | 38 | @Override 39 | public void peerStateChanged(CallPeerChangeEvent evt) 40 | { 41 | super.peerStateChanged(evt); 42 | 43 | CallPeer peer = evt.getSourceCallPeer(); 44 | if (targetState.equals(peer.getState())) 45 | { 46 | synchronized (this) 47 | { 48 | this.notifyAll(); 49 | } 50 | } 51 | } 52 | 53 | public void waitForState(Call call, 54 | int peerIdx, 55 | CallPeerState targetState, 56 | long timeout) 57 | throws InterruptedException 58 | { 59 | this.targetState = targetState; 60 | 61 | CallPeer watchedPeer = getCallPeer(call, peerIdx); 62 | 63 | // FIXME: we can miss call state anyway ?(but timeout will release) 64 | if (!targetState.equals(watchedPeer.getState())) 65 | { 66 | synchronized (this) 67 | { 68 | watchedPeer.addCallPeerListener(this); 69 | 70 | this.wait(timeout); 71 | } 72 | } 73 | 74 | watchedPeer.removeCallPeerListener(this); 75 | 76 | assertEquals(targetState, watchedPeer.getState()); 77 | } 78 | 79 | private CallPeer getCallPeer(Call call, int peerIdx) 80 | { 81 | if (peerIdx >= call.getCallPeerCount()) 82 | throw new IllegalArgumentException( 83 | "Peers idx: " + peerIdx 84 | + " per count: " + call.getCallPeerCount()); 85 | 86 | Iterator peers = call.getCallPeers(); 87 | CallPeer watchedPeer = peers.next(); 88 | for (int i=0; i < peerIdx; i++) 89 | { 90 | watchedPeer = peers.next(); 91 | } 92 | 93 | return watchedPeer; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockProtocolProviderFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | 22 | import org.osgi.framework.*; 23 | 24 | import java.util.*; 25 | 26 | /** 27 | * 28 | */ 29 | public class MockProtocolProviderFactory 30 | extends ProtocolProviderFactory 31 | { 32 | 33 | /** 34 | * Creates a new ProtocolProviderFactory. 35 | * 36 | * @param bundleContext the bundle context reference of the service 37 | * @param protocolName the name of the protocol 38 | */ 39 | public MockProtocolProviderFactory( 40 | BundleContext bundleContext, 41 | String protocolName) 42 | { 43 | super(bundleContext, protocolName); 44 | } 45 | 46 | @Override 47 | public AccountID installAccount(String userID, 48 | Map accountProperties) 49 | throws IllegalArgumentException, IllegalStateException, 50 | NullPointerException 51 | { 52 | throw new UnsupportedOperationException(); 53 | } 54 | 55 | @Override 56 | public void modifyAccount(ProtocolProviderService protocolProvider, 57 | Map accountProperties) 58 | throws NullPointerException 59 | { 60 | throw new UnsupportedOperationException(); 61 | } 62 | 63 | @Override 64 | protected AccountID createAccountID(String userID, 65 | Map accountProperties) 66 | { 67 | return new MockAccountID(userID, accountProperties, getProtocolName()); 68 | } 69 | 70 | @Override 71 | protected ProtocolProviderService createService(String userID, 72 | AccountID accountID) 73 | { 74 | MockProtocolProvider protocolProvider 75 | = new MockProtocolProvider((MockAccountID) accountID); 76 | 77 | protocolProvider.includeBasicTeleOpSet(); 78 | 79 | if (ProtocolNames.JABBER.equals(getProtocolName())) 80 | { 81 | protocolProvider.includeMultiUserChatOpSet(); 82 | protocolProvider.includeJitsiMeetToolsJabber(); 83 | } 84 | if (ProtocolNames.SIP.equals(getProtocolName())) 85 | { 86 | protocolProvider.includeJitsiMeetToolsSip(); 87 | } 88 | 89 | return protocolProvider; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscriptionRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import javax.media.format.*; 21 | import java.util.*; 22 | import java.util.concurrent.*; 23 | 24 | /** 25 | * A TranscriptionRequest serves as a holder for some audio fragment 26 | * which needs to be transcribed 27 | * 28 | * @author Nik Vaessen 29 | */ 30 | public class TranscriptionRequest 31 | { 32 | 33 | /** 34 | * The audio which needs to be transcribed 35 | */ 36 | private byte[] audio; 37 | 38 | /** 39 | * The AudioFormat of the audio in this instance 40 | */ 41 | private AudioFormat format; 42 | 43 | /** 44 | * The Locale of the audio. It is expected to contain both a Language 45 | * and a region, at the minimum 46 | */ 47 | private Locale locale; 48 | 49 | /** 50 | * Create a TranscriptionRequest which holds the audio to be 51 | * transcribed along with its AudioFormat 52 | * 53 | * @param audio the audio fragment to be transcribed as an array of bytes 54 | * @param format the format of the given audio fragment 55 | * @param locale the locale of the audio being spoken 56 | */ 57 | public TranscriptionRequest(byte[] audio, AudioFormat format, 58 | Locale locale) 59 | { 60 | this.audio = audio; 61 | this.format = format; 62 | this.locale = locale; 63 | } 64 | 65 | /** 66 | * Get the length of the audio in this {@link TranscriptionRequest} in 67 | * milliseconds 68 | * 69 | * @return the duration of the audio in milliseconds or -1 when unknown 70 | */ 71 | public long getDurationInMs() 72 | { 73 | if (this.format == null) 74 | { 75 | return -1; 76 | } 77 | 78 | return TimeUnit.NANOSECONDS.toMillis( 79 | this.format.computeDuration(this.audio.length)); 80 | } 81 | 82 | 83 | /** 84 | * The audio this instance is holding 85 | * 86 | * @return an audio fragment as an array of bytes 87 | */ 88 | public byte[] getAudio() 89 | { 90 | return audio; 91 | } 92 | 93 | /** 94 | * Get the format of the audio this instance is holding 95 | * 96 | * @return the AudioFormat of the audio of this instance 97 | */ 98 | public AudioFormat getFormat() 99 | { 100 | return format; 101 | } 102 | 103 | /** 104 | * Get the Locale of the audio 105 | * 106 | * @return the locale of the audio 107 | */ 108 | public Locale getLocale() 109 | { 110 | return locale; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/WhisperConnectionPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2023 8x8 Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.jigasi.util.Util; 21 | import org.jitsi.utils.logging.*; 22 | 23 | import java.io.*; 24 | import java.util.*; 25 | import java.util.concurrent.*; 26 | 27 | /** 28 | * The singleton class manages the WebSocket connections to the Whisper 29 | * service. We chose to have a single connection per room instead 30 | * of a single connection per Participant. 31 | * The WebSocket will disconnect when all Participants left the room. 32 | * 33 | * @author rpurdel 34 | */ 35 | public class WhisperConnectionPool 36 | { 37 | /** 38 | * The logger class 39 | */ 40 | private final static Logger logger = Logger.getLogger(WhisperConnectionPool.class); 41 | 42 | /** 43 | * The singleton instance to be returned 44 | */ 45 | private static WhisperConnectionPool instance = null; 46 | 47 | /** 48 | * A hashmap holding the state for each connection 49 | */ 50 | private final Map pool = new ConcurrentHashMap<>(); 51 | 52 | /** 53 | * Gets a connection if it exists, creates one if it doesn't. 54 | * @param roomId The room jid. 55 | * @return The websocket. 56 | */ 57 | public WhisperWebsocket getConnection(String roomId) 58 | { 59 | if (!pool.containsKey(roomId)) 60 | { 61 | logger.info("Room " + roomId + " doesn't exist. Creating a new connection."); 62 | final WhisperWebsocket socket = new WhisperWebsocket(); 63 | 64 | socket.connect(); 65 | 66 | pool.put(roomId, socket); 67 | } 68 | 69 | return pool.get(roomId); 70 | } 71 | 72 | /** 73 | * Ends the connection if all participants have left the room 74 | * @param roomId The room jid. 75 | * @param participantId The participant id. 76 | */ 77 | public void end(String roomId, String participantId) 78 | { 79 | WhisperWebsocket wsConn = pool.getOrDefault(roomId, null); 80 | if (wsConn == null) 81 | { 82 | return; 83 | } 84 | 85 | wsConn.disconnectParticipant(participantId, allDisconnected -> 86 | { 87 | if (allDisconnected) 88 | { 89 | pool.remove(roomId); 90 | } 91 | }); 92 | } 93 | 94 | /** 95 | * Static method to return the instance of the class 96 | * @return The connection pool. 97 | */ 98 | public static WhisperConnectionPool getInstance() 99 | { 100 | synchronized (WhisperConnectionPool.class) 101 | { 102 | if (instance == null) 103 | { 104 | instance = new WhisperConnectionPool(); 105 | } 106 | } 107 | 108 | return instance; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/RemotePublisherTranscriptionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.jigasi.*; 21 | import org.json.simple.*; 22 | 23 | import java.util.*; 24 | 25 | /** 26 | * Pushes transcriptions to remote services. 27 | * 28 | * @author Damian Minkov 29 | */ 30 | public class RemotePublisherTranscriptionHandler 31 | extends LocalJsonTranscriptHandler 32 | implements TranscriptionEventListener 33 | { 34 | /** 35 | * List of remote services to notify for transcriptions. 36 | */ 37 | private List urls = new ArrayList<>(); 38 | 39 | /** 40 | * Constructs RemotePublisherTranscriptionHandler, initializing its config. 41 | * 42 | * @param urlsStr String containing urls of remote services, separated 43 | * by ','. 44 | */ 45 | public RemotePublisherTranscriptionHandler(String urlsStr) 46 | { 47 | super(); 48 | 49 | // initialize tokens 50 | StringTokenizer tokens = new StringTokenizer(urlsStr, ","); 51 | while (tokens.hasMoreTokens()) 52 | { 53 | urls.add(tokens.nextToken().trim()); 54 | } 55 | } 56 | 57 | @Override 58 | public void publish(JvbConference jvbConference, TranscriptionResult result) 59 | { 60 | if (result.isInterim()) 61 | return; 62 | 63 | JSONObject eventObject = createTranscriptionJSONObject(result); 64 | 65 | eventObject.put( 66 | LocalJsonTranscriptHandler 67 | .JSON_KEY_FINAL_TRANSCRIPT_ROOM_NAME, 68 | result.getParticipant().getTranscriber().getRoomName()); 69 | 70 | // adds event type to the encapsulating object to be consistent 71 | // with the events we push to the remote service 72 | eventObject.put( 73 | LocalJsonTranscriptHandler 74 | .JSON_KEY_EVENT_EVENT_TYPE, 75 | Transcript.TranscriptEventType.SPEECH.toString()); 76 | 77 | for (String url : urls) 78 | { 79 | Util.postJSON(url, eventObject); 80 | } 81 | } 82 | 83 | @Override 84 | public void notify(Transcriber transcriber, TranscriptEvent event) 85 | { 86 | JSONObject object = new JSONObject(); 87 | object.put( 88 | JSON_KEY_FINAL_TRANSCRIPT_ROOM_NAME, 89 | transcriber.getRoomName()); 90 | 91 | if (event.getEvent() == Transcript.TranscriptEventType.JOIN 92 | || event.getEvent() == Transcript.TranscriptEventType.LEAVE) 93 | { 94 | addEventDescriptions(object, event); 95 | } 96 | else if (event.getEvent() == Transcript.TranscriptEventType.START 97 | || event.getEvent() == Transcript.TranscriptEventType.END) 98 | { 99 | object.put(JSON_KEY_EVENT_EVENT_TYPE, 100 | event.getEvent().toString()); 101 | object.put(JSON_KEY_EVENT_TIMESTAMP, 102 | event.getTimeStamp().toEpochMilli()); 103 | } 104 | 105 | for (String url : urls) 106 | { 107 | Util.postJSON(url, object); 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/test/java/org/jitsi/jigasi/OSGiHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi; 19 | 20 | import java.util.*; 21 | import net.java.sip.communicator.service.protocol.*; 22 | import net.java.sip.communicator.service.protocol.mock.*; 23 | import net.java.sip.communicator.util.osgi.*; 24 | import org.jitsi.jigasi.osgi.*; 25 | import org.osgi.framework.*; 26 | import org.osgi.framework.launch.*; 27 | 28 | /** 29 | * Helper class takes encapsulates OSGi specifics operations. 30 | * 31 | * @author Pawel Domas 32 | */ 33 | public class OSGiHandler 34 | { 35 | private BundleContext bc; 36 | 37 | public Framework init() 38 | throws InterruptedException, BundleException 39 | { 40 | System.setProperty( 41 | "net.java.sip.communicator.impl.configuration.USE_PROPFILE_CONFIG", 42 | "true"); 43 | 44 | // Disable SingleCallInProgressPolicy 45 | System.setProperty( 46 | "net.java.sip.communicator.impl.protocol.SingleCallInProgressPolicy" 47 | + ".enabled", 48 | "false" 49 | ); 50 | 51 | JigasiBundleConfig.setSystemPropertyDefaults(); 52 | var fw = Main.start(List.of( 53 | MockSipActivator.class, 54 | MockProtocolProviderFactoriesActivator.class)); 55 | bc = fw.getBundleContext(); 56 | return fw; 57 | } 58 | 59 | public static class MockSipActivator 60 | extends DependentActivator 61 | { 62 | public MockSipActivator() 63 | { 64 | super(ProtocolProviderFactory.class); 65 | } 66 | 67 | @Override 68 | public void startWithServices(BundleContext context) 69 | { 70 | Map accProps = new HashMap<>(); 71 | accProps.put(CallContext.DOMAIN_BASE_ACCOUNT_PROP, "sipserver.net"); 72 | MockAccountID mockSipAccount 73 | = new MockAccountID("sipuser@sipserver.net", 74 | accProps, 75 | ProtocolNames.SIP); 76 | 77 | var sipProvider = new MockProtocolProvider(mockSipAccount); 78 | sipProvider.includeBasicTeleOpSet(); 79 | sipProvider.includeJitsiMeetToolsSip(); 80 | 81 | var properties = new Hashtable(); 82 | properties.put(ProtocolProviderFactory.PROTOCOL, ProtocolNames.SIP); 83 | properties.put(ProtocolProviderFactory.USER_ID, 84 | "sipuser@sipserver.net"); 85 | context.registerService(ProtocolProviderService.class, sipProvider, 86 | properties); 87 | } 88 | 89 | @Override 90 | public void stop(BundleContext context) 91 | { 92 | } 93 | } 94 | 95 | public MockProtocolProvider getSipProvider() throws InvalidSyntaxException 96 | { 97 | var filter = 98 | "(&(" + ProtocolProviderFactory.PROTOCOL + "=" + ProtocolNames.SIP 99 | + ")" 100 | + "(" + ProtocolProviderFactory.USER_ID 101 | + "=sipuser@sipserver.net))"; 102 | var ref = bc.getServiceReferences(ProtocolProviderService.class, filter) 103 | .stream() 104 | .findFirst() 105 | .orElseThrow(); 106 | return (MockProtocolProvider) bc.getService(ref); 107 | } 108 | 109 | public SipGateway getSipGateway() 110 | { 111 | return ServiceUtils.getService(bc, SipGateway.class); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /script/graceful_shutdown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 1. The script issues shutdown command to jigasi over REST API. 4 | # If HTTP status code other than 200 is returned then it exits with 1. 5 | # 2. If the code is ok then it checks if jigasi has exited. 6 | # 3. If not then it polls jigasi statistics until conference count drops to 0. 7 | # 4. Gives some time for jigasi to shutdown. If it does not quit after that 8 | # time then it kills the process. If the process was successfully killed 0 is 9 | # returned and 1 otherwise. 10 | # 11 | # Arguments: 12 | # "-p"(mandatory) the PID of jigasi process 13 | # "-h"("http://localhost:8788" by default) REST requests host URI part 14 | # "-t"("25" by default) number of second we we for jigadi to shutdown 15 | # gracefully after conference count drops to 0 16 | # "-s"(disabled by default) enable silent mode - no info output 17 | # 18 | # NOTE: script depends on the tool jq, used to parse json 19 | # 20 | 21 | # Initialize arguments 22 | hostUrl="http://localhost:8788" 23 | timeout=25 24 | verbose=1 25 | 26 | # Parse arguments 27 | OPTIND=1 28 | while getopts "p:h:t:s" opt; do 29 | case "$opt" in 30 | p) 31 | pid=$OPTARG 32 | ;; 33 | h) 34 | hostUrl=$OPTARG 35 | ;; 36 | t) 37 | timeout=$OPTARG 38 | ;; 39 | s) 40 | verbose=0 41 | ;; 42 | esac 43 | done 44 | shift "$((OPTIND-1))" 45 | 46 | # Try the pid file, if no pid was provided as an argument. 47 | # for systemd we use different pid file in a subfolder 48 | if [ "$pid" = "" ] ;then 49 | if [ -f /var/run/jigasi.pid ]; then 50 | pid=`cat /var/run/jigasi.pid` 51 | elif [ -f /var/run/jigasi/jigasi/pid ]; then 52 | pid=`cat /var/run/jigasi/jigasi.pid` 53 | else 54 | pid=`ps aux | grep jigasi.jar | grep -v grep | awk '{print $2}'` 55 | fi 56 | fi 57 | 58 | #Check if PID is a number 59 | re='^[0-9]+$' 60 | if ! [[ $pid =~ $re ]] ; then 61 | echo "error: PID is not a number" >&2; exit 1 62 | fi 63 | 64 | # Returns conference count by calling JVB REST statistics API and extracting 65 | # conference count from JSON stats text returned. 66 | function getConferenceCount { 67 | statsjson=$(curl -s "$hostUrl/about/stats") 68 | # echo $statsjson 69 | stats=$(echo $statsjson| jq '. ["conferences"]') 70 | echo $stats 71 | } 72 | 73 | # Prints info messages 74 | function printInfo { 75 | if [ "$verbose" == "1" ] 76 | then 77 | echo "$@" 78 | fi 79 | } 80 | 81 | # Prints errors 82 | function printError { 83 | echo "$@" 1>&2 84 | } 85 | 86 | shutdownStatus=`curl -s -o /dev/null -H "Content-Type: application/json" -d '{ "graceful-shutdown": "true" }' -w "%{http_code}" "$hostUrl/about/shutdown"` 87 | if [ "$shutdownStatus" == "200" ] 88 | then 89 | printInfo "Graceful shutdown started" 90 | confCount=`getConferenceCount` 91 | while [[ $confCount -gt 0 ]] ; do 92 | printInfo "There are still $confCount conferences" 93 | sleep 10 94 | confCount=`getConferenceCount` 95 | done 96 | 97 | sleep 5 98 | 99 | if ps -p $pid > /dev/null 2>&1 100 | then 101 | printInfo "It is still running, lets give it $timeout seconds" 102 | sleep $timeout 103 | if ps -p $pid > /dev/null 2>&1 104 | then 105 | printError "Jigasi did not exit after $timeout sec - killing $pid" 106 | kill $pid 107 | else 108 | printInfo "Jigasi shutdown OK" 109 | exit 0 110 | fi 111 | else 112 | printInfo "Jigasi shutdown OK" 113 | exit 0 114 | fi 115 | # check for 3 seconds if we managed to kill 116 | for I in 1 2 3 117 | do 118 | if ps -p $pid > /dev/null 2>&1 119 | then 120 | sleep 1 121 | fi 122 | done 123 | if ps -p $pid > /dev/null 2>&1 124 | then 125 | printError "Failed to kill $pid" 126 | printError "Sending force kill to $pid" 127 | kill -9 $pid 128 | if ps -p $pid > /dev/null 2>&1 129 | then 130 | printError "Failed to force kill $pid" 131 | exit 1 132 | fi 133 | fi 134 | rm -f /var/run/jigasi.pid 135 | rm -f /var/run/jigasi/jigasi.pid 136 | printInfo "Jigasi shutdown OK" 137 | exit 0 138 | else 139 | printError "Invalid HTTP status for shutdown request: $shutdownStatus" 140 | exit 1 141 | fi 142 | 143 | 144 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/SilenceFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import org.jitsi.webrtcvadwrapper.*; 21 | import org.jitsi.webrtcvadwrapper.audio.*; 22 | 23 | /** 24 | * This class uses {@link SpeechDetector) to 25 | * detect silent audio. 26 | * 27 | * @author Nik Vaessen 28 | */ 29 | public class SilenceFilter 30 | { 31 | /** 32 | * The vad mode which should be used for the {@link WebRTCVad}. 33 | */ 34 | private static final int VAD_MODE = 1; 35 | 36 | /** 37 | * The sample rate of the audio given to {@link WebRTCVad}. 38 | */ 39 | private static final int VAD_AUDIO_HZ = 48000; 40 | 41 | /** 42 | * The length of each consecutive segment which is given to the 43 | * {@link WebRTCVad}. 44 | */ 45 | private static final int VAD_SEGMENT_SIZE_MS = 20; 46 | 47 | /** 48 | * The length of the audio which is considered when determining speech. 49 | * In this case 10 segments (as defined above) are considered. 50 | */ 51 | private static final int VAD_WINDOW_SIZE_MS = 200; 52 | 53 | /** 54 | * The audio is considered as silent when 8 out of 10 previous segments 55 | * where determined to be not speech. 56 | */ 57 | private static final int VAD_THRESHOLD = 8; 58 | 59 | /** 60 | * The {@link SpeechDetector} object used to detect silent audio. 61 | */ 62 | private SpeechDetector speechDetector 63 | = new SpeechDetector<>( 64 | VAD_AUDIO_HZ, 65 | VAD_MODE, 66 | VAD_SEGMENT_SIZE_MS, 67 | VAD_WINDOW_SIZE_MS, 68 | VAD_THRESHOLD); 69 | 70 | /** 71 | * Whether the previously given segment was determined to be speech. 72 | */ 73 | private boolean previousSegmentWasSpeech; 74 | 75 | /** 76 | * Whether the latest speech segment was determined to be speech. 77 | */ 78 | private boolean isCurrentlySpeech; 79 | 80 | /** 81 | * Give a new segment of audio 82 | * 83 | * @param audio the audio 84 | */ 85 | public void giveSegment(byte[] audio) 86 | { 87 | ByteSignedPcmAudioSegment segment 88 | = new ByteSignedPcmAudioSegment(audio); 89 | 90 | speechDetector.nextSegment(segment); 91 | previousSegmentWasSpeech = isCurrentlySpeech; 92 | isCurrentlySpeech = speechDetector.isSpeech(); 93 | } 94 | 95 | /** 96 | * Get the whole window size in a single array. 97 | * 98 | * @return the whole window as an array of bytes. 99 | */ 100 | public byte[] getSpeechWindow() 101 | { 102 | return ByteSignedPcmAudioSegment 103 | .merge(speechDetector.getLatestSegments()) 104 | .getAudio(); 105 | } 106 | 107 | /** 108 | * Whether the current window is considered to be speech. 109 | * @return 110 | */ 111 | public boolean shouldFilter() 112 | { 113 | return !speechDetector.isSpeech(); 114 | } 115 | 116 | /** 117 | * Whether the last given segment indicated that the audio transistioned 118 | * from silence to speech, which means the whole window is now 119 | * considered speech. 120 | * 121 | * @return true when a transition from silence to speech took place. 122 | */ 123 | public boolean newSpeech() 124 | { 125 | return !previousSegmentWasSpeech && isCurrentlySpeech; 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockJitsiMeetTools.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.impl.protocol.jabber.*; 21 | import net.java.sip.communicator.service.protocol.*; 22 | import org.jitsi.utils.logging.Logger; 23 | import org.jivesoftware.smack.packet.*; 24 | import org.json.simple.*; 25 | 26 | import java.util.*; 27 | import java.util.concurrent.*; 28 | 29 | /** 30 | * @author Pawel Domas 31 | */ 32 | public class MockJitsiMeetTools 33 | implements OperationSetJitsiMeetTools, OperationSetJitsiMeetToolsJabber 34 | { 35 | /** 36 | * The logger used by this class. 37 | */ 38 | private final static Logger logger 39 | = Logger.getLogger(MockJitsiMeetTools.class); 40 | 41 | private final MockProtocolProvider protocolProvider; 42 | 43 | /** 44 | * The list of {@link JitsiMeetRequestListener}. 45 | */ 46 | private final List requestHandlers 47 | = new CopyOnWriteArrayList<>(); 48 | 49 | public MockJitsiMeetTools(MockProtocolProvider protocolProvider) 50 | { 51 | this.protocolProvider = protocolProvider; 52 | } 53 | 54 | public MockCall mockIncomingGatewayCall(String uri, String roomName) 55 | { 56 | return protocolProvider.getTelephony() 57 | .mockIncomingGatewayCall(uri, roomName); 58 | } 59 | 60 | /** 61 | * {@inheritDoc} 62 | */ 63 | @Override 64 | public void addRequestListener(JitsiMeetRequestListener requestHandler) 65 | { 66 | this.requestHandlers.add(requestHandler); 67 | } 68 | 69 | /** 70 | * {@inheritDoc} 71 | */ 72 | @Override 73 | public void removeRequestListener(JitsiMeetRequestListener requestHandler) 74 | { 75 | this.requestHandlers.remove(requestHandler); 76 | } 77 | 78 | /** 79 | * Notifies all registered {@link JitsiMeetRequestListener} about incoming 80 | * call that contains name of the MUC room which is hosting Jitsi Meet 81 | * conference. 82 | * @param call the incoming {@link Call} instance. 83 | * @param jitsiMeetRoom the name of the chat room of Jitsi Meet conference 84 | * to be joined. 85 | */ 86 | public void notifyJoinJitsiMeetRoom(Call call, String jitsiMeetRoom) 87 | { 88 | boolean handled = false; 89 | for (JitsiMeetRequestListener l : requestHandlers) 90 | { 91 | l.onJoinJitsiMeetRequest( 92 | call, jitsiMeetRoom, new HashMap<>()); 93 | handled = true; 94 | } 95 | if (!handled) 96 | { 97 | logger.warn( 98 | "Unhandled join Jitsi Meet request R:" + jitsiMeetRoom 99 | + " C: " + call); 100 | } 101 | } 102 | 103 | @Override 104 | public void sendJSON(CallPeer callPeer, JSONObject jsonObject, Map map) 105 | { 106 | } 107 | 108 | @Override 109 | public void addSupportedFeature(String featureName) 110 | { 111 | 112 | } 113 | 114 | @Override 115 | public void removeSupportedFeature(String featureName) 116 | { 117 | 118 | } 119 | 120 | @Override 121 | public void sendPresenceExtension(ChatRoom chatRoom, 122 | ExtensionElement extension) 123 | { 124 | 125 | } 126 | 127 | @Override 128 | public void removePresenceExtension(ChatRoom chatRoom, 129 | ExtensionElement extension) 130 | { 131 | 132 | } 133 | 134 | @Override 135 | public void setPresenceStatus(ChatRoom chatRoom, String statusMessage) 136 | { 137 | 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/muc/MockMucShare.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock.muc; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | import net.java.sip.communicator.service.protocol.event.*; 22 | 23 | import java.util.*; 24 | import org.jitsi.utils.logging.Logger; 25 | 26 | /** 27 | * The purpose of this class is to simulate mock room joined by all 28 | * {@link net.java.sip.communicator.service.protocol.mock.MockProtocolProvider}s 29 | * only if they share the same room name. 30 | * 31 | * @author Pawel Domas 32 | */ 33 | public class MockMucShare 34 | implements ChatRoomMemberPresenceListener 35 | { 36 | private final static Logger logger = Logger.getLogger(MockMucShare.class); 37 | 38 | private final String roomName; 39 | 40 | private List groupedChats 41 | = new ArrayList(); 42 | 43 | public MockMucShare(String roomName) 44 | { 45 | this.roomName = roomName; 46 | } 47 | 48 | public void nextRoomCreated(MockMultiUserChat chatRoom) 49 | { 50 | synchronized(groupedChats) 51 | { 52 | groupedChats.add(chatRoom); 53 | } 54 | 55 | chatRoom.addMemberPresenceListener(this); 56 | 57 | // Copy existing members if any 58 | for (ChatRoomMember member : chatRoom.getMembers()) 59 | { 60 | broadcastMemberJoined(chatRoom, member); 61 | } 62 | } 63 | 64 | @Override 65 | public void memberPresenceChanged(ChatRoomMemberPresenceChangeEvent evt) 66 | { 67 | String eventType = evt.getEventType(); 68 | 69 | if (ChatRoomMemberPresenceChangeEvent.MEMBER_JOINED.equals(eventType)) 70 | { 71 | broadcastMemberJoined(evt.getChatRoom(), evt.getChatRoomMember()); 72 | } 73 | else if( 74 | ChatRoomMemberPresenceChangeEvent.MEMBER_KICKED.equals(eventType) 75 | || ChatRoomMemberPresenceChangeEvent.MEMBER_LEFT.equals(eventType) 76 | || ChatRoomMemberPresenceChangeEvent.MEMBER_QUIT.equals(eventType) ) 77 | { 78 | broadcastMemberLeft(evt.getChatRoom(), evt.getChatRoomMember()); 79 | } 80 | else 81 | { 82 | logger.warn("Unsupported event type: " + eventType); 83 | } 84 | } 85 | 86 | private void broadcastMemberJoined(ChatRoom chatRoom, 87 | ChatRoomMember chatRoomMember) 88 | { 89 | List listeners; 90 | synchronized(groupedChats) 91 | { 92 | listeners = new ArrayList<>(groupedChats); 93 | } 94 | 95 | for (MockMultiUserChat chatToNotify : listeners) 96 | { 97 | if (chatToNotify != chatRoom) 98 | { 99 | chatToNotify.removeMemberPresenceListener(this); 100 | 101 | chatToNotify.mockJoin((MockRoomMember) chatRoomMember); 102 | 103 | chatToNotify.addMemberPresenceListener(this); 104 | } 105 | } 106 | } 107 | 108 | private void broadcastMemberLeft(ChatRoom chatRoom, 109 | ChatRoomMember chatRoomMember) 110 | { 111 | List listeners; 112 | synchronized(groupedChats) 113 | { 114 | listeners = new ArrayList<>(groupedChats); 115 | } 116 | 117 | for (MockMultiUserChat chatToNotify : listeners) 118 | { 119 | if (chatToNotify != chatRoom) 120 | { 121 | chatToNotify.mockLeave(chatRoomMember.getName()); 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/muc/MockMultiUserChatOpSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock.muc; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | 22 | import java.util.*; 23 | 24 | /** 25 | * @author Pawel Domas 26 | */ 27 | public class MockMultiUserChatOpSet 28 | extends AbstractOperationSetMultiUserChat 29 | { 30 | private static final Map mucDomainSharing 31 | = new HashMap(); 32 | 33 | private final ProtocolProviderService protocolProviderService; 34 | 35 | private final Map chatRooms 36 | = new HashMap(); 37 | 38 | public MockMultiUserChatOpSet( 39 | ProtocolProviderService protocolProviderService) 40 | { 41 | this.protocolProviderService = protocolProviderService; 42 | } 43 | 44 | @Override 45 | public List getExistingChatRooms() 46 | throws OperationFailedException, OperationNotSupportedException 47 | { 48 | synchronized (chatRooms) 49 | { 50 | return new ArrayList(chatRooms.keySet()); 51 | } 52 | } 53 | 54 | @Override 55 | public List getCurrentlyJoinedChatRooms() 56 | { 57 | return null; 58 | } 59 | 60 | @Override 61 | public List getCurrentlyJoinedChatRooms( 62 | ChatRoomMember chatRoomMember) 63 | throws OperationFailedException, OperationNotSupportedException 64 | { 65 | return null; 66 | } 67 | 68 | @Override 69 | public ChatRoom createChatRoom(String roomName, 70 | Map roomProperties) 71 | throws OperationFailedException, OperationNotSupportedException 72 | { 73 | synchronized (chatRooms) 74 | { 75 | if (chatRooms.containsKey(roomName)) 76 | { 77 | throw new OperationFailedException( 78 | "Room " + roomName + " already exists.", 79 | OperationFailedException.GENERAL_ERROR); 80 | } 81 | 82 | MockMultiUserChat chatRoom 83 | = new MockMultiUserChat(roomName, protocolProviderService); 84 | 85 | chatRooms.put(roomName, chatRoom); 86 | 87 | MockMucShare sharedDomain = mucDomainSharing.get(roomName); 88 | if (sharedDomain == null) 89 | { 90 | sharedDomain = new MockMucShare(roomName); 91 | 92 | mucDomainSharing.put(roomName, sharedDomain); 93 | } 94 | 95 | sharedDomain.nextRoomCreated(chatRoom); 96 | 97 | return chatRoom; 98 | } 99 | } 100 | 101 | @Override 102 | public ChatRoom findRoom(String roomName) 103 | throws OperationFailedException, OperationNotSupportedException 104 | { 105 | synchronized (chatRooms) 106 | { 107 | if (!chatRooms.containsKey(roomName)) 108 | { 109 | ChatRoom room = createChatRoom(roomName, null); 110 | chatRooms.put(roomName, (MockMultiUserChat) room); 111 | } 112 | return chatRooms.get(roomName); 113 | } 114 | } 115 | 116 | @Override 117 | public void rejectInvitation(ChatRoomInvitation invitation, 118 | String rejectReason) 119 | { 120 | 121 | } 122 | 123 | @Override 124 | public boolean isMultiChatSupportedByContact(Contact contact) 125 | { 126 | return false; 127 | } 128 | 129 | @Override 130 | public boolean isPrivateMessagingContact(String contactAddress) 131 | { 132 | return false; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/health/Health.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.health; 19 | 20 | import org.jitsi.jigasi.*; 21 | import org.jitsi.utils.concurrent.*; 22 | 23 | /** 24 | * Checks the health of Jigasi. 25 | * 26 | * @author Damian Minkov 27 | */ 28 | public class Health 29 | { 30 | /** 31 | * The executor used to perform periodic health checks. 32 | */ 33 | private static final RecurringRunnableExecutor executor 34 | = new RecurringRunnableExecutor(Health.class.getName()); 35 | 36 | /** 37 | * The current sip checker. 38 | */ 39 | private static SipHealthPeriodicChecker sipChecker = null; 40 | 41 | /** 42 | * Whether there is a SipGateway returned from the list of 43 | * available gateways. 44 | */ 45 | private static boolean hasSipGw = false; 46 | 47 | /** 48 | * Starts a runnable which checks the health of jigasi 49 | * periodically (at an interval). 50 | */ 51 | public static void start() 52 | { 53 | SipGateway sipGateway = null; 54 | for (AbstractGateway gw : JigasiBundleActivator.getAvailableGateways()) 55 | { 56 | if (gw instanceof SipGateway) 57 | sipGateway = (SipGateway) gw; 58 | } 59 | 60 | if (sipGateway != null) 61 | { 62 | hasSipGw = true; 63 | 64 | if (sipGateway.isReady()) 65 | { 66 | sipChecker = SipHealthPeriodicChecker.create(sipGateway); 67 | if (sipChecker != null) 68 | { 69 | executor.registerRecurringRunnable(sipChecker); 70 | } 71 | } 72 | else 73 | { 74 | // we will wait for the sip gw to become ready and will try 75 | // to start it again 76 | final SipGateway finalSipGw = sipGateway; 77 | sipGateway.addGatewayListener(new GatewayListener() 78 | { 79 | @Override 80 | public void onReady() 81 | { 82 | finalSipGw.removeGatewayListener(this); 83 | start(); 84 | } 85 | }); 86 | } 87 | } 88 | } 89 | 90 | /** 91 | * Stops running health checks. 92 | */ 93 | public static void stop() 94 | { 95 | if (sipChecker != null) 96 | { 97 | executor.deRegisterRecurringRunnable(sipChecker); 98 | sipChecker = null; 99 | } 100 | } 101 | 102 | /** 103 | * Checks the health (status). This method only returns the cache results, 104 | * it does not do the actual health check 105 | * (i.e. creating a test conference/call). 106 | * 107 | * @throws Exception if an error occurs while checking the health (status) 108 | * or the check determines that is not healthy. 109 | */ 110 | public static void check() 111 | throws Exception 112 | { 113 | if (!CallManager.isHealthy()) 114 | { 115 | throw new Exception("CallManager is not healthy."); 116 | } 117 | 118 | if (sipChecker != null) 119 | { 120 | sipChecker.check(); 121 | } 122 | else 123 | { 124 | if (hasSipGw) 125 | { 126 | // we have sip gw, but no sipChecker, means gw is not ready yet 127 | throw new Exception("GW not ready."); 128 | } 129 | 130 | if (JigasiBundleActivator.getAvailableGateways().isEmpty()) 131 | { 132 | throw new Exception("No gateways configured."); 133 | } 134 | // currently we do not check the health of the transcription gateway 135 | // it is always healthy 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockBasicTeleOpSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | import net.java.sip.communicator.service.protocol.event.*; 22 | import net.java.sip.communicator.service.protocol.media.*; 23 | 24 | import java.text.*; 25 | import java.util.*; 26 | 27 | /** 28 | * 29 | * @author Pawel Domas 30 | */ 31 | public class MockBasicTeleOpSet 32 | extends AbstractOperationSetBasicTelephony 33 | { 34 | private final MockProtocolProvider protocolProvider; 35 | 36 | private List activeCalls = new ArrayList(); 37 | 38 | 39 | public MockBasicTeleOpSet(MockProtocolProvider protocolProvider) 40 | { 41 | this.protocolProvider = protocolProvider; 42 | } 43 | 44 | @Override 45 | public synchronized Call createCall(String uri, CallConference conference) 46 | throws OperationFailedException, ParseException 47 | { 48 | MockCall outgoingCall = new MockCall(this); 49 | 50 | MockCallPeer peer = new MockCallPeer(uri, outgoingCall); 51 | 52 | outgoingCall.addCallPeer(peer); 53 | 54 | activeCalls.add(outgoingCall); 55 | 56 | fireCallEvent(CallEvent.CALL_INITIATED, outgoingCall); 57 | 58 | return outgoingCall; 59 | } 60 | 61 | @Override 62 | public void answerCallPeer(CallPeer peer) 63 | throws OperationFailedException 64 | { 65 | 66 | ((MockCallPeer) peer).setState(CallPeerState.CONNECTED); 67 | 68 | ((MockCall) peer.getCall()).setCallState(CallState.CALL_IN_PROGRESS); 69 | } 70 | 71 | @Override 72 | public void putOnHold(CallPeer peer) 73 | throws OperationFailedException 74 | { 75 | ((MockCallPeer) peer).putOnHold(); 76 | } 77 | 78 | @Override 79 | public void putOffHold(CallPeer peer) 80 | throws OperationFailedException 81 | { 82 | ((MockCallPeer) peer).putOffHold(); 83 | } 84 | 85 | @Override 86 | public void hangupCallPeer(CallPeer peer) 87 | throws OperationFailedException 88 | { 89 | ((MockCall)peer.getCall()).hangup(); 90 | } 91 | 92 | @Override 93 | public void hangupCallPeer(CallPeer peer, int reasonCode, String reason) 94 | throws OperationFailedException 95 | { 96 | hangupCallPeer(peer); 97 | } 98 | 99 | @Override 100 | public synchronized Iterator getActiveCalls() 101 | { 102 | return activeCalls.iterator(); 103 | } 104 | 105 | @Override 106 | public MockProtocolProvider getProtocolProvider() 107 | { 108 | return protocolProvider; 109 | } 110 | 111 | public synchronized MockCall createIncomingCall(String calee) 112 | { 113 | MockCall incomingCall = new MockCall(this); 114 | 115 | MockCallPeer peer = new MockCallPeer(calee, incomingCall); 116 | 117 | incomingCall.addCallPeer(peer); 118 | 119 | activeCalls.add(incomingCall); 120 | 121 | fireCallEvent(CallEvent.CALL_RECEIVED, incomingCall); 122 | 123 | return incomingCall; 124 | } 125 | 126 | public MockCall mockIncomingGatewayCall(String uri, final String roomName) 127 | { 128 | final MockCall call = createIncomingCall(uri); 129 | 130 | // Gateway incoming call looks at the beginning like normal call, 131 | // but then "join jitsi meet room" event is fired. 132 | // It happens after CALL_RECEIVED event(done in createIncomingCall). 133 | 134 | if (!CallState.CALL_ENDED.equals(call.getCallState())) 135 | { 136 | getProtocolProvider() 137 | .getJitsiMeetTools() 138 | .notifyJoinJitsiMeetRoom(call, roomName); 139 | } 140 | 141 | return call; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockCallPeer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.service.protocol.*; 21 | import net.java.sip.communicator.service.protocol.event.*; 22 | import net.java.sip.communicator.service.protocol.media.*; 23 | import org.jitsi.service.neomedia.*; 24 | import org.jitsi.utils.*; 25 | import org.jitsi.utils.logging.Logger; 26 | 27 | /** 28 | * @author Pawel Domas 29 | */ 30 | public class MockCallPeer 31 | extends MediaAwareCallPeer 33 | { 34 | /** 35 | * The logger. 36 | */ 37 | private final static Logger logger = Logger.getLogger(MockCallPeer.class); 38 | 39 | private final String address; 40 | 41 | private final MockCall call; 42 | 43 | public MockCallPeer(String address, MockCall call) 44 | { 45 | super(call); 46 | 47 | this.address = address; 48 | this.call = call; 49 | 50 | setMediaHandler(new MockPeerMediaHandler(this, null)); 51 | } 52 | 53 | @Override 54 | public void addConferenceMembersSoundLevelListener( 55 | ConferenceMembersSoundLevelListener listener) 56 | { 57 | 58 | } 59 | 60 | @Override 61 | public void addStreamSoundLevelListener(SoundLevelListener listener) 62 | { 63 | 64 | } 65 | 66 | @Override 67 | public String getAddress() 68 | { 69 | return address; 70 | } 71 | 72 | @Override 73 | public MockCall getCall() 74 | { 75 | return call; 76 | } 77 | 78 | @Override 79 | public Contact getContact() 80 | { 81 | return null; 82 | } 83 | 84 | @Override 85 | public String getDisplayName() 86 | { 87 | return null; 88 | } 89 | 90 | @Override 91 | public byte[] getImage() 92 | { 93 | return new byte[0]; 94 | } 95 | 96 | @Override 97 | public String getPeerID() 98 | { 99 | return null; 100 | } 101 | 102 | @Override 103 | public String getURI() 104 | { 105 | return null; 106 | } 107 | 108 | @Override 109 | public void removeConferenceMembersSoundLevelListener( 110 | ConferenceMembersSoundLevelListener listener) 111 | { 112 | 113 | } 114 | 115 | @Override 116 | public void removeStreamSoundLevelListener(SoundLevelListener listener) 117 | { 118 | 119 | } 120 | 121 | private CallPeerState lastState; 122 | 123 | @Override 124 | public void setState(CallPeerState newState, String reason, int reasonCode) 125 | { 126 | this.lastState = getState(); 127 | 128 | super.setState(newState, reason, reasonCode); 129 | } 130 | 131 | @Override 132 | public String getEntity() 133 | { 134 | throw new UnsupportedOperationException("getEntity"); 135 | } 136 | 137 | @Override 138 | public MediaDirection getDirection(MediaType mediaType) 139 | { 140 | throw new UnsupportedOperationException("getDirection"); 141 | } 142 | 143 | public void putOnHold() 144 | { 145 | try 146 | { 147 | getMediaHandler().setLocallyOnHold(true); 148 | setState(CallPeerState.ON_HOLD_LOCALLY); 149 | logger.info(this + " is now on hold, last state: " + lastState); 150 | } 151 | catch (OperationFailedException e) 152 | { 153 | throw new RuntimeException(e); 154 | } 155 | } 156 | 157 | public void putOffHold() 158 | { 159 | try 160 | { 161 | getMediaHandler().setLocallyOnHold(false); 162 | setState(lastState); 163 | logger.info(this + " is now off hold, switch to: " + lastState); 164 | } 165 | catch (OperationFailedException e) 166 | { 167 | throw new RuntimeException(e); 168 | } 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /src/test/java/net/java/sip/communicator/service/protocol/mock/MockProtocolProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2015 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package net.java.sip.communicator.service.protocol.mock; 19 | 20 | import net.java.sip.communicator.impl.protocol.jabber.*; 21 | import net.java.sip.communicator.service.protocol.*; 22 | import net.java.sip.communicator.service.protocol.event.*; 23 | import net.java.sip.communicator.service.protocol.mock.muc.*; 24 | 25 | /** 26 | * 27 | * @author Pawel Domas 28 | */ 29 | public class MockProtocolProvider 30 | extends AbstractProtocolProviderService 31 | { 32 | private final MockAccountID accountId; 33 | 34 | private RegistrationState registrationState 35 | = RegistrationState.UNREGISTERED; 36 | 37 | public MockProtocolProvider(MockAccountID accountId) 38 | { 39 | this.accountId = accountId; 40 | } 41 | 42 | @Override 43 | public void register(SecurityAuthority authority) 44 | throws OperationFailedException 45 | { 46 | setRegistrationState( 47 | RegistrationState.REGISTERED, 48 | RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, 49 | null); 50 | } 51 | 52 | private void setRegistrationState(RegistrationState newState, 53 | int reasonCode, 54 | String reason) 55 | { 56 | RegistrationState oldState = getRegistrationState(); 57 | 58 | this.registrationState = newState; 59 | 60 | fireRegistrationStateChanged( 61 | oldState, newState, reasonCode, reason); 62 | } 63 | 64 | @Override 65 | public void unregister() 66 | throws OperationFailedException 67 | { 68 | setRegistrationState( 69 | RegistrationState.UNREGISTERED, 70 | RegistrationStateChangeEvent.REASON_NOT_SPECIFIED, 71 | null); 72 | } 73 | 74 | @Override 75 | public RegistrationState getRegistrationState() 76 | { 77 | return registrationState; 78 | } 79 | 80 | @Override 81 | public String getProtocolName() 82 | { 83 | return accountId.getProtocolName(); 84 | } 85 | 86 | @Override 87 | public ProtocolIcon getProtocolIcon() 88 | { 89 | return null; 90 | } 91 | 92 | @Override 93 | public void shutdown() 94 | { 95 | 96 | } 97 | 98 | @Override 99 | public AccountID getAccountID() 100 | { 101 | return accountId; 102 | } 103 | 104 | @Override 105 | public boolean isSignalingTransportSecure() 106 | { 107 | return false; 108 | } 109 | 110 | @Override 111 | public TransportProtocol getTransportProtocol() 112 | { 113 | return null; 114 | } 115 | 116 | 117 | public void includeBasicTeleOpSet() 118 | { 119 | addSupportedOperationSet( 120 | OperationSetBasicTelephony.class, 121 | new MockBasicTeleOpSet(this)); 122 | } 123 | 124 | public void includeMultiUserChatOpSet() 125 | { 126 | addSupportedOperationSet( 127 | OperationSetMultiUserChat.class, 128 | new MockMultiUserChatOpSet(this)); 129 | } 130 | 131 | public void includeJitsiMeetToolsJabber() 132 | { 133 | addSupportedOperationSet( 134 | OperationSetJitsiMeetToolsJabber.class, 135 | new MockJitsiMeetTools(this)); 136 | } 137 | public void includeJitsiMeetToolsSip() 138 | { 139 | addSupportedOperationSet( 140 | OperationSetJitsiMeetTools.class, 141 | new MockJitsiMeetTools(this)); 142 | } 143 | 144 | public MockJitsiMeetTools getJitsiMeetTools() 145 | { 146 | return (MockJitsiMeetTools) 147 | getOperationSet(OperationSetJitsiMeetTools.class); 148 | } 149 | 150 | public MockBasicTeleOpSet getTelephony() 151 | { 152 | return (MockBasicTeleOpSet) getOperationSet( 153 | OperationSetBasicTelephony.class); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/LibreTranslateTranslationService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import com.google.gson.Gson; 21 | import com.google.gson.GsonBuilder; 22 | import org.apache.http.HttpResponse; 23 | import org.apache.http.client.methods.HttpPost; 24 | import org.apache.http.entity.ContentType; 25 | import org.apache.http.entity.StringEntity; 26 | import org.apache.http.impl.client.HttpClientBuilder; 27 | import org.apache.http.impl.client.CloseableHttpClient; 28 | import org.apache.http.util.EntityUtils; 29 | import org.jitsi.jigasi.JigasiBundleActivator; 30 | import org.jitsi.utils.logging.Logger; 31 | import java.io.IOException; 32 | 33 | 34 | /** 35 | * Implements a {@link TranslationService} which will use LibreTranslate API to translate the given text from one 36 | * language to another. 37 | *

38 | * LibreTranslate 39 | * for more information about LibreTranslate 40 | * @author Pinglei He 41 | */ 42 | public class LibreTranslateTranslationService 43 | implements TranslationService 44 | { 45 | /* 46 | * Class representing the json response body from LibreTranslate where response has status code 200. 47 | * Used for json-to-POJO conversion with Gson. 48 | */ 49 | class LibreTranslateResponse 50 | { 51 | private String translatedText; 52 | 53 | public String getTranslatedText() 54 | { 55 | return translatedText; 56 | } 57 | } 58 | 59 | /* 60 | * The URL of the LibreTranslate API. 61 | */ 62 | public final String API_URL = "org.jitsi.jigasi.transcription.libreTranslate.api_url"; 63 | 64 | public final String DEFAULT_API_URL = "http://libretranslate:5000/translate"; 65 | 66 | private final String apiUrl; 67 | 68 | private final Logger logger = Logger.getLogger(LibreTranslateTranslationService.class); 69 | 70 | public LibreTranslateTranslationService() 71 | { 72 | apiUrl = JigasiBundleActivator.getConfigurationService().getString(API_URL, DEFAULT_API_URL); 73 | } 74 | 75 | /** 76 | * {@inheritDoc} 77 | */ 78 | @Override 79 | public String translate(String sourceText, String sourceLang, String targetLang) 80 | { 81 | String payload = "{" 82 | .concat("\"q\": \"" + sourceText + "\",") 83 | .concat("\"source\": \"" + sourceLang.substring(0, 2) + "\",") 84 | .concat("\"target\": \"" + targetLang.substring(0, 2) + "\",") 85 | .concat("\"format\": \"text\",") 86 | .concat("\"api_key\": \"\"") 87 | .concat("}"); 88 | 89 | StringEntity entity = new StringEntity(payload, ContentType.APPLICATION_JSON); 90 | 91 | HttpResponse response; 92 | try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) 93 | { 94 | HttpPost request = new HttpPost(apiUrl); 95 | request.setEntity(entity); 96 | request.setHeader("Accept", "application/json"); 97 | request.setHeader("Content-type", "application/json"); 98 | response = httpClient.execute(request); 99 | String jsonBody = EntityUtils.toString(response.getEntity()); 100 | int statusCode = response.getStatusLine().getStatusCode(); 101 | if (statusCode != 200) 102 | { 103 | logger.error("LibreTranslate responded with status code " + statusCode + "."); 104 | logger.error(jsonBody); 105 | return ""; 106 | } 107 | Gson gson = new GsonBuilder().create(); 108 | LibreTranslateResponse translateResponse = gson.fromJson(jsonBody, LibreTranslateResponse.class); 109 | return translateResponse.getTranslatedText(); 110 | } 111 | catch (IOException e) 112 | { 113 | logger.error("Error during request to LibreTranslate service."); 114 | logger.error(e.toString()); 115 | return ""; 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/osgi/JigasiBundleConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2018 - present 8x8, Inc. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.osgi; 19 | 20 | import java.util.*; 21 | import net.java.sip.communicator.impl.protocol.jabber.*; 22 | import org.jitsi.impl.neomedia.*; 23 | import org.jitsi.impl.neomedia.device.*; 24 | import org.jitsi.impl.neomedia.transform.csrc.*; 25 | import org.jitsi.service.configuration.*; 26 | 27 | /** 28 | * Jigasi OSGi bundle config 29 | * 30 | * @author Pawel Domas 31 | */ 32 | public class JigasiBundleConfig 33 | { 34 | private JigasiBundleConfig() 35 | { 36 | // prevent instances 37 | } 38 | 39 | /** 40 | * Returns a {@code Map} which contains default system properties common to 41 | * all server components. Currently, we have the following values there: 42 | *

  • {@link ConfigurationService#PNAME_CONFIGURATION_FILE_IS_READ_ONLY} 43 | * = true
  • 44 | *
  • {@link MediaServiceImpl#DISABLE_AUDIO_SUPPORT_PNAME} = true
  • 45 | *
  • {@link MediaServiceImpl#DISABLE_VIDEO_SUPPORT_PNAME} = true
  • 46 | * 47 | * @return a {@code Map} which contains default system properties common to 48 | * all server components 49 | */ 50 | private static Map getSystemPropertyDefaults() 51 | { 52 | // XXX A default System property value specified bellow will eventually 53 | // be set only if the System property in question does not have a value 54 | // set yet. 55 | 56 | Map defaults = new HashMap<>(); 57 | String true_ = Boolean.toString(true); 58 | String false_ = Boolean.toString(false); 59 | 60 | // Disable Video 61 | defaults.put( 62 | "net.java.sip.communicator.service.media.DISABLE_VIDEO_SUPPORT", 63 | true_); 64 | 65 | // Audio system should not be disabled 66 | defaults.put( 67 | MediaServiceImpl.DISABLE_AUDIO_SUPPORT_PNAME, 68 | false_); 69 | 70 | defaults.put( 71 | DeviceConfiguration.PROP_AUDIO_SYSTEM, 72 | AudioSystem.LOCATOR_PROTOCOL_AUDIOSILENCE); 73 | defaults.put( 74 | "org.jitsi.impl.neomedia.device.PortAudioSystem.disabled", 75 | true_); 76 | defaults.put( 77 | "org.jitsi.impl.neomedia.device.PulseAudioSystem.disabled", 78 | true_); 79 | 80 | // Disables COIN notifications 81 | defaults.put( 82 | OperationSetTelephonyConferencingJabberImpl.DISABLE_COIN_PROP_NAME, 83 | true_); 84 | 85 | // FIXME not sure about this one 86 | // It makes no sense for Jitsi Videobridge to pace its RTP output. 87 | defaults.put( 88 | DeviceConfiguration.PROP_VIDEO_RTP_PACING_THRESHOLD, 89 | Integer.toString(Integer.MAX_VALUE)); 90 | 91 | /* 92 | * Drops silent audio packets that has the 93 | * rtp extension(rfc6464) with sound level information. 94 | */ 95 | defaults.put( 96 | SsrcTransformEngine 97 | .DROP_MUTED_AUDIO_SOURCE_IN_REVERSE_TRANSFORM, 98 | true_); 99 | 100 | // override defaults with passed to the Main 101 | defaults.put( 102 | ConfigurationService.PNAME_CONFIGURATION_FILE_IS_READ_ONLY, 103 | System.getProperty( 104 | ConfigurationService.PNAME_CONFIGURATION_FILE_IS_READ_ONLY, 105 | true_)); 106 | 107 | return defaults; 108 | } 109 | 110 | /** 111 | * Sets default system properties required to run Jitsi libraries inside of 112 | * a server component. The purpose of that is to disable audio/video input 113 | * devices etc. 114 | */ 115 | public static void setSystemPropertyDefaults() 116 | { 117 | Map defaults = getSystemPropertyDefaults(); 118 | 119 | for (Map.Entry e : defaults.entrySet()) 120 | { 121 | String key = e.getKey(); 122 | 123 | if (System.getProperty(key) == null) 124 | System.setProperty(key, e.getValue()); 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscriptEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import java.time.*; 21 | 22 | /** 23 | * Describe an TranscriptEvent which took place at a certain time and 24 | * can belong to a named person 25 | * 26 | * @author Nik Vaessen 27 | */ 28 | public class TranscriptEvent 29 | implements Comparable 30 | { 31 | /** 32 | * The time when the event took place 33 | */ 34 | private Instant timeStamp; 35 | 36 | /** 37 | * The participant who caused this event. Will be null if 38 | * {@link this#event} is {@link Transcript.TranscriptEventType#START} or 39 | * {@link Transcript.TranscriptEventType#END} 40 | */ 41 | private Participant participant; 42 | 43 | /** 44 | * The type of event this object is representing 45 | */ 46 | private Transcript.TranscriptEventType event; 47 | 48 | /** 49 | * Create a TranscriptEvent which has a TimeStamp and a name 50 | * 51 | * @param timeStamp the time the event took place 52 | * @param participant the name of who caused this event 53 | * @param event the event this object will describe 54 | */ 55 | TranscriptEvent(Instant timeStamp, Participant participant, 56 | Transcript.TranscriptEventType event) 57 | { 58 | this.timeStamp = timeStamp; 59 | this.participant = participant; 60 | this.event = event; 61 | } 62 | 63 | /** 64 | * Create a TranscriptEvent which has a TimeStamp. This is only for 65 | * events {@link Transcript.TranscriptEventType#START} and 66 | * {@link Transcript.TranscriptEventType#END} 67 | * 68 | * @param timeStamp the time the event took place 69 | * @param event either {@link Transcript.TranscriptEventType#START} or 70 | * {@link Transcript.TranscriptEventType#END} 71 | * @throws IllegalArgumentException when event is not correct type 72 | */ 73 | TranscriptEvent(Instant timeStamp, Transcript.TranscriptEventType event) 74 | { 75 | if (Transcript.TranscriptEventType.END.equals(event) 76 | || Transcript.TranscriptEventType.WILL_END.equals(event) 77 | || Transcript.TranscriptEventType.START.equals(event)) 78 | { 79 | this.timeStamp = timeStamp; 80 | this.event = event; 81 | } 82 | else 83 | { 84 | throw new IllegalArgumentException("TranscriptEvent " + event + 85 | " needs a participant"); 86 | } 87 | } 88 | 89 | /** 90 | * Get the Instant of when this event took place 91 | * 92 | * @return the instant 93 | */ 94 | public Instant getTimeStamp() 95 | { 96 | return timeStamp; 97 | } 98 | 99 | /** 100 | * Get the name of the person who caused this event 101 | * 102 | * @return the name as a String 103 | */ 104 | public String getName() 105 | { 106 | return participant.getName(); 107 | } 108 | 109 | /** 110 | * Get the id (jid) of the person who caused this event 111 | * 112 | * @return the id as a String 113 | */ 114 | public String getID() 115 | { 116 | return participant.getId(); 117 | } 118 | 119 | /** 120 | * Get what kind of event this is 121 | 122 | * @return the kind of event 123 | */ 124 | public Transcript.TranscriptEventType getEvent() 125 | { 126 | return event; 127 | } 128 | 129 | /** 130 | * Events can be compared by the TimeStamp they took place. When another 131 | * event took place earlier than this one, it is compared as smaller 132 | * (< 0), when it took place at exactly the same time, they are equal 133 | * (0), and when another event took place later, it is bigger (> 0) 134 | * 135 | * @return negative int when smaller, 0 when equal, positive int when 136 | * bigger 137 | * @throws NullPointerException when other is null 138 | */ 139 | @Override 140 | public int compareTo(TranscriptEvent other) 141 | throws NullPointerException 142 | { 143 | return this.timeStamp.compareTo(other.timeStamp); 144 | } 145 | 146 | /** 147 | * Overwritten to have expected behaviour with compareTo method 148 | */ 149 | @Override 150 | public boolean equals(Object obj) 151 | { 152 | return obj instanceof TranscriptEvent && 153 | this.timeStamp.equals(((TranscriptEvent) obj).timeStamp); 154 | } 155 | 156 | /** 157 | * Returns the participant for this event if any. 158 | * @return the participant for this event if any. 159 | */ 160 | public Participant getParticipant() 161 | { 162 | return participant; 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/transcription/TranscriptionService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Jigasi, the JItsi GAteway to SIP. 3 | * 4 | * Copyright @ 2017 Atlassian Pty Ltd 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | package org.jitsi.jigasi.transcription; 19 | 20 | import java.util.function.*; 21 | 22 | /** 23 | * A TranscriptionService provides the ability to send audio either 24 | * as complete audio fragments or as a continuous stream of audio packets 25 | * to a speech-to-text API for transcription. 26 | * 27 | * Fragments of audio are assumed to lie in the range of 15 to 60 seconds 28 | * of audio. 29 | * 30 | * A continuous stream of audio packets has no expected maximum duration. 31 | * 32 | * @author Nik Vaessen 33 | */ 34 | public interface TranscriptionService 35 | { 36 | /** 37 | * Get whether this TranscriptionService supports sending fragments of audio 38 | * 39 | * @return true when fragmented transcription is supported, false otherwise 40 | */ 41 | boolean supportsFragmentTranscription(); 42 | 43 | /** 44 | * Sends an audio fragment request to the service to be transcribed. 45 | * The fragment of audio should contain at least one spoken word for 46 | * transcription to be successful. Fragments longer than 60 seconds 47 | * might not be supported by most speech-to-text or will require 48 | * to much processing time to get a timely answer. 49 | * 50 | * @param request the TranscriptionRequest which holds the audio 51 | * @param resultConsumer a Consumer of the transcription result 52 | * @throws UnsupportedOperationException when this service does not support 53 | * fragmented audio speech-to-text 54 | */ 55 | void sendSingleRequest(TranscriptionRequest request, 56 | Consumer resultConsumer) 57 | throws UnsupportedOperationException; 58 | 59 | /** 60 | * Get whether this TranscriptionService supports sending a continuous 61 | * stream of audio packets 62 | * 63 | * @return true when streaming transcription is supported, false otherwise 64 | */ 65 | boolean supportsStreamRecognition(); 66 | 67 | /** 68 | * Get whether this TranscriptionService supports language routing to 69 | * redirect data to different websockets 70 | * 71 | * @return true when language routing is supported, false otherwise 72 | */ 73 | boolean supportsLanguageRouting(); 74 | 75 | /** 76 | * Initialise a session which sends a continuous stream of audio to the 77 | * service to be transcribed 78 | * 79 | * @param participant the participant starting the session. 80 | * @return a session which can be given new packets and which can be polled 81 | * or subscribed to for new incoming transcription results 82 | * @throws UnsupportedOperationException when the service does not support 83 | * streaming speech-to-text 84 | */ 85 | StreamingRecognitionSession initStreamingSession(Participant participant) 86 | throws UnsupportedOperationException; 87 | 88 | /** 89 | * Get whether this service is properly configured and able to connect 90 | * to the service 91 | * 92 | * @return true when properly configured, false otherwise 93 | */ 94 | boolean isConfiguredProperly(); 95 | 96 | /** 97 | * An interface for a session managing the transcription of a stream of 98 | * audio. Allows giving small packets of audio as well as subscribing 99 | * (multiple) listener(s) which will retrieve TranscriptionResults 100 | * The AudioFormat and Locale of the audio are not expected to 101 | * change during the session 102 | */ 103 | interface StreamingRecognitionSession 104 | { 105 | /** 106 | * Give the next fragment of audio on the continuous stream of 107 | * audio. 108 | * 109 | * @param request a TranscriptionRequest which holds the next fragment 110 | * of audio in a continuous stream 111 | */ 112 | void sendRequest(TranscriptionRequest request); 113 | 114 | /** 115 | * Gracefully end the session. Audio which was send but has not been 116 | * transcribed should still be processed 117 | */ 118 | void end(); 119 | 120 | /** 121 | * Get whether this StreamingRecognitionSession has already been told 122 | * to stop or has been stopped 123 | * 124 | * @return true when the session is stopping or has been stopped 125 | */ 126 | boolean ended(); 127 | 128 | /** 129 | * Add a TranscriptionListener which will be notified when a new 130 | * transcription result will come in 131 | * 132 | * @param listener a listener which should be notified of any incoming 133 | * results 134 | */ 135 | void addTranscriptionListener(TranscriptionListener listener); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/org/jitsi/jigasi/version/AbstractVersionActivator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright @ 2015 - present, 8x8 Inc 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.jitsi.jigasi.version; 17 | 18 | import org.jitsi.utils.version.*; 19 | import org.jitsi.utils.version.Version; 20 | 21 | import org.jitsi.utils.logging.*; 22 | import org.osgi.framework.*; 23 | 24 | import java.util.regex.*; 25 | 26 | /** 27 | *

    28 | * The entry point to the {@code VersionService} implementation. We register the 29 | * {@code VersionServiceImpl} instance on the OSGi bus. 30 | *

    31 | *

    32 | * This abstract BundleActivator will provide implementation of 33 | * the VersionService once {@link #getCurrentVersion()} method is 34 | * provided. 35 | *

    36 | * 37 | * @author George Politis 38 | * @author Pawel Domas 39 | */ 40 | public abstract class AbstractVersionActivator 41 | implements BundleActivator 42 | { 43 | /** 44 | * The Logger used by this VersionActivator instance for 45 | * logging output. 46 | */ 47 | private final Logger logger 48 | = Logger.getLogger(AbstractVersionActivator.class); 49 | 50 | /** 51 | * The pattern that will parse strings to version object. 52 | */ 53 | private static final Pattern PARSE_VERSION_STRING_PATTERN 54 | = Pattern.compile("(\\d+)\\.(\\d+)\\.([\\d\\.]+)"); 55 | 56 | /** 57 | * Implementing class must return a valid {@link Version} object. 58 | * 59 | * @return {@link Version} instance which provides the details about 60 | * current version of the application. 61 | */ 62 | abstract protected Version getCurrentVersion(); 63 | 64 | /** 65 | * Called when this bundle is started so the Framework can perform the 66 | * bundle-specific activities necessary to start this bundle. 67 | * 68 | * @param context The execution context of the bundle being started. 69 | * @throws Exception If this method throws an exception, this bundle is 70 | * marked as stopped and the Framework will remove this bundle's listeners, 71 | * unregister all services registered by this bundle, and release all 72 | * services used by this bundle. 73 | */ 74 | public void start(BundleContext context) throws Exception 75 | { 76 | if (logger.isDebugEnabled()) 77 | { 78 | logger.debug("Started."); 79 | } 80 | 81 | Version currentVersion = getCurrentVersion(); 82 | 83 | VersionServiceImpl versionServiceImpl 84 | = new VersionServiceImpl(currentVersion); 85 | 86 | context.registerService( 87 | VersionService.class.getName(), 88 | versionServiceImpl, 89 | null); 90 | 91 | logger.info("VersionService registered: " 92 | + currentVersion.getApplicationName() + " " + currentVersion); 93 | } 94 | 95 | /** 96 | * Called when this bundle is stopped so the Framework can perform the 97 | * bundle-specific activities necessary to stop the bundle. 98 | * 99 | * @param context The execution context of the bundle being stopped. 100 | * @throws Exception If this method throws an exception, the bundle is still 101 | * marked as stopped, and the Framework will remove the bundle's listeners, 102 | * unregister all services registered by the bundle, and release all 103 | * services used by the bundle. 104 | */ 105 | public void stop(BundleContext context) throws Exception 106 | { 107 | } 108 | 109 | /** 110 | * Implementation of the {@link VersionService}. 111 | */ 112 | static class VersionServiceImpl 113 | implements VersionService 114 | { 115 | private final Version version; 116 | 117 | private VersionServiceImpl(Version version) 118 | { 119 | this.version = version; 120 | } 121 | 122 | /** 123 | * Returns a Version instance corresponding to the version 124 | * string. 125 | * 126 | * @param versionString a version String that we have obtained by calling a 127 | * Version.toString() method. 128 | * 129 | * @return the Version object corresponding to the 130 | * version string. Or null if we cannot parse the string. 131 | */ 132 | @Override 133 | public Version parseVersionString(String versionString) 134 | { 135 | Matcher matcher 136 | = PARSE_VERSION_STRING_PATTERN.matcher(versionString); 137 | 138 | if (matcher.matches() && matcher.groupCount() == 3) 139 | { 140 | return new VersionImpl( 141 | version.getApplicationName(), 142 | Integer.parseInt(matcher.group(1)), 143 | Integer.parseInt(matcher.group(2)), 144 | matcher.group(3), 145 | version.getPreReleaseID()); 146 | } 147 | 148 | return null; 149 | } 150 | 151 | /** 152 | * Returns a Version object containing version details of the 153 | * the application version that we're currently running. 154 | * 155 | * @return a Version object containing version details of the 156 | * application version that we're currently running. 157 | */ 158 | @Override 159 | public Version getCurrentVersion() 160 | { 161 | return version; 162 | } 163 | } 164 | } 165 | --------------------------------------------------------------------------------