mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-23 21:17:58 +01:00
Jingle Session Establishment Refactoring
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@7457 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
parent
4a86390b17
commit
41fbc3906a
7 changed files with 289 additions and 72 deletions
|
@ -496,7 +496,7 @@ public class JingleManager implements JingleSessionListener {
|
||||||
jingleSession.removeListener(this);
|
jingleSession.removeListener(this);
|
||||||
jingleSessions.remove(jingleSession);
|
jingleSessions.remove(jingleSession);
|
||||||
jingleSession.close();
|
jingleSession.close();
|
||||||
System.err.println("Declined");
|
System.err.println("Declined:"+reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
public void sessionRedirected(String redirection, JingleSession jingleSession) {
|
||||||
|
|
|
@ -98,8 +98,8 @@ public class ICECandidate extends TransportCandidate implements Comparable {
|
||||||
* @param type type as defined in ICE-12
|
* @param type type as defined in ICE-12
|
||||||
*/
|
*/
|
||||||
public ICECandidate(String ip, int generation, int network,
|
public ICECandidate(String ip, int generation, int network,
|
||||||
String password, int port, String username,
|
String password, int port, String username,
|
||||||
int preference, String type) {
|
int preference, String type) {
|
||||||
super(ip, port, generation);
|
super(ip, port, generation);
|
||||||
|
|
||||||
proto = Protocol.UDP;
|
proto = Protocol.UDP;
|
||||||
|
@ -252,50 +252,61 @@ public class ICECandidate extends TransportCandidate implements Comparable {
|
||||||
|
|
||||||
Thread checkThread = new Thread(new Runnable() {
|
Thread checkThread = new Thread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
boolean isUsable = false;
|
|
||||||
|
final TestResult result = new TestResult();
|
||||||
|
|
||||||
// Media Proxy don´t have Echo features.
|
// Media Proxy don´t have Echo features.
|
||||||
// If its a relayed candidate we assumpt that is Checked.
|
// If its a relayed candidate we assumpt that is NOT Valid while other candidates still being checked.
|
||||||
|
// The negotiator MUST add then in the correct situations
|
||||||
if (getType().equals("relay")) {
|
if (getType().equals("relay")) {
|
||||||
try {
|
triggerCandidateChecked(false);
|
||||||
Thread.sleep(TransportNegotiator.CANDIDATES_ACCEPT_PERIOD*2);
|
|
||||||
}
|
|
||||||
catch (InterruptedException e) {
|
|
||||||
// Do Nothing
|
|
||||||
}
|
|
||||||
triggerCandidateChecked(true);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ResultListener resultListener = new ResultListener() {
|
||||||
|
public void testFinished(TestResult testResult) {
|
||||||
|
if (testResult.isReachable()) {
|
||||||
|
result.setResult(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (TransportCandidate candidate : localCandidates) {
|
for (TransportCandidate candidate : localCandidates) {
|
||||||
CandidateEcho echo = candidate.getCandidateEcho();
|
CandidateEcho echo = candidate.getCandidateEcho();
|
||||||
if (echo != null) {
|
if (echo != null) {
|
||||||
try {
|
if (candidate instanceof ICECandidate) {
|
||||||
InetAddress address = InetAddress.getByName(getIp());
|
ICECandidate iceCandidate = (ICECandidate) candidate;
|
||||||
if (echo.test(address, getPort(),2000)) isUsable = true;
|
if (!iceCandidate.getType().equals("relay")) {
|
||||||
if (isUsable) break;
|
try {
|
||||||
}
|
echo.addResultListener(resultListener);
|
||||||
catch (UnknownHostException e) {
|
InetAddress address = InetAddress.getByName(getIp());
|
||||||
e.printStackTrace();
|
echo.testASync(address, getPort());
|
||||||
|
}
|
||||||
|
catch (UnknownHostException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isUsable) {
|
for (int i = 0; i < 10 && !result.isReachable(); i++)
|
||||||
System.out.println("Checked using UDP Echo:" + getLocalIp());
|
try {
|
||||||
triggerCandidateChecked(isUsable);
|
System.err.println(i);
|
||||||
return;
|
Thread.sleep(300);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (TransportCandidate candidate : localCandidates) {
|
||||||
|
CandidateEcho echo = candidate.getCandidateEcho();
|
||||||
|
if (echo != null) {
|
||||||
|
echo.removeResultListener(resultListener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InetAddress candAddress;
|
triggerCandidateChecked(result.isReachable());
|
||||||
try {
|
|
||||||
candAddress = InetAddress.getByName(getIp());
|
|
||||||
isUsable = candAddress.isReachable(TransportResolver.CHECK_TIMEOUT);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
isUsable = false;
|
|
||||||
}
|
|
||||||
triggerCandidateChecked(isUsable);
|
|
||||||
|
|
||||||
//TODO candidate is being checked trigger
|
//TODO candidate is being checked trigger
|
||||||
//candidatesChecking.remove(cand);
|
//candidatesChecking.remove(cand);
|
||||||
|
@ -327,14 +338,16 @@ public class ICECandidate extends TransportCandidate implements Comparable {
|
||||||
if (other.getChannel() != null) {
|
if (other.getChannel() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!getChannel().equals(other.getChannel())) {
|
}
|
||||||
|
else if (!getChannel().equals(other.getChannel())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getId() == null) {
|
if (getId() == null) {
|
||||||
if (other.getId() != null) {
|
if (other.getId() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!getId().equals(other.getId())) {
|
}
|
||||||
|
else if (!getId().equals(other.getId())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getNetwork() != other.getNetwork()) {
|
if (getNetwork() != other.getNetwork()) {
|
||||||
|
@ -344,7 +357,8 @@ public class ICECandidate extends TransportCandidate implements Comparable {
|
||||||
if (other.getPassword() != null) {
|
if (other.getPassword() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!getPassword().equals(other.password)) {
|
}
|
||||||
|
else if (!getPassword().equals(other.password)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getPreference() != other.getPreference()) {
|
if (getPreference() != other.getPreference()) {
|
||||||
|
@ -354,14 +368,16 @@ public class ICECandidate extends TransportCandidate implements Comparable {
|
||||||
if (other.getProto() != null) {
|
if (other.getProto() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!getProto().equals(other.getProto())) {
|
}
|
||||||
|
else if (!getProto().equals(other.getProto())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (getUsername() == null) {
|
if (getUsername() == null) {
|
||||||
if (other.getUsername() != null) {
|
if (other.getUsername() != null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (!getUsername().equals(other.getUsername())) {
|
}
|
||||||
|
else if (!getUsername().equals(other.getUsername())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -370,9 +386,11 @@ public class ICECandidate extends TransportCandidate implements Comparable {
|
||||||
public boolean isNull() {
|
public boolean isNull() {
|
||||||
if (super.isNull()) {
|
if (super.isNull()) {
|
||||||
return true;
|
return true;
|
||||||
} else if (getProto().isNull()) {
|
}
|
||||||
|
else if (getProto().isNull()) {
|
||||||
return true;
|
return true;
|
||||||
} else if (getChannel().isNull()) {
|
}
|
||||||
|
else if (getChannel().isNull()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -391,7 +409,8 @@ public class ICECandidate extends TransportCandidate implements Comparable {
|
||||||
ICECandidate tc = (ICECandidate) arg;
|
ICECandidate tc = (ICECandidate) arg;
|
||||||
if (getPreference() < tc.getPreference()) {
|
if (getPreference() < tc.getPreference()) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (getPreference() > tc.getPreference()) {
|
}
|
||||||
|
else if (getPreference() > tc.getPreference()) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright 2003-2005 Jive Software.
|
||||||
|
*
|
||||||
|
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.jingle.nat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener for ECHO Test Results
|
||||||
|
*
|
||||||
|
* @author Thiago Camargo
|
||||||
|
*/
|
||||||
|
public interface ResultListener {
|
||||||
|
|
||||||
|
public void testFinished(TestResult result);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* $RCSfile$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002-2006 Jive Software. All rights reserved.
|
||||||
|
* ====================================================================
|
||||||
|
* The Jive Software License (based on Apache Software License, Version 1.1)
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The end-user documentation included with the redistribution,
|
||||||
|
* if any, must include the following acknowledgment:
|
||||||
|
* "This product includes software developed by
|
||||||
|
* Jive Software (http://www.jivesoftware.com)."
|
||||||
|
* Alternately, this acknowledgment may appear in the software itself,
|
||||||
|
* if and wherever such third-party acknowledgments normally appear.
|
||||||
|
*
|
||||||
|
* 4. The names "Smack" and "Jive Software" must not be used to
|
||||||
|
* endorse or promote products derived from this software without
|
||||||
|
* prior written permission. For written permission, please
|
||||||
|
* contact webmaster@jivesoftware.com.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "Smack",
|
||||||
|
* nor may "Smack" appear in their name, without prior written
|
||||||
|
* permission of Jive Software.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jivesoftware.smackx.jingle.nat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result of an ECHO Test
|
||||||
|
*
|
||||||
|
* @author Thiago Camargo
|
||||||
|
*/
|
||||||
|
public class TestResult {
|
||||||
|
|
||||||
|
private boolean result = false;
|
||||||
|
|
||||||
|
public boolean isReachable() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResult(boolean result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -649,12 +649,13 @@ public abstract class TransportCandidate {
|
||||||
DatagramSocket socket = null;
|
DatagramSocket socket = null;
|
||||||
byte password[] = null;
|
byte password[] = null;
|
||||||
List<DatagramListener> listeners = new ArrayList<DatagramListener>();
|
List<DatagramListener> listeners = new ArrayList<DatagramListener>();
|
||||||
|
List<ResultListener> resultListeners = new ArrayList<ResultListener>();
|
||||||
boolean enabled = true;
|
boolean enabled = true;
|
||||||
boolean ended = false;
|
boolean ended = false;
|
||||||
long tries = 10;
|
long tries = 10;
|
||||||
|
|
||||||
public CandidateEcho(TransportCandidate candidate) throws UnknownHostException, SocketException {
|
public CandidateEcho(TransportCandidate candidate) throws UnknownHostException, SocketException {
|
||||||
this.socket = new DatagramSocket(candidate.getPort(), InetAddress.getByName("0.0.0.0"));
|
this.socket = new DatagramSocket(candidate.getPort(), InetAddress.getByName(candidate.getLocalIp()));
|
||||||
Random r = new Random();
|
Random r = new Random();
|
||||||
password = longToByteArray((Math.abs(r.nextLong())));
|
password = longToByteArray((Math.abs(r.nextLong())));
|
||||||
}
|
}
|
||||||
|
@ -712,27 +713,30 @@ public abstract class TransportCandidate {
|
||||||
socket.close();
|
socket.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fireTestResult(TestResult testResult) {
|
||||||
|
for (ResultListener resultListener : resultListeners)
|
||||||
|
resultListener.testFinished(testResult);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean test(final InetAddress address, final int port) {
|
public boolean test(final InetAddress address, final int port) {
|
||||||
return test(address, port, 2000);
|
return test(address, port, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean test(final InetAddress address, final int port, int timeout) {
|
public boolean test(final InetAddress address, final int port, int timeout) {
|
||||||
|
|
||||||
ended=false;
|
ended = false;
|
||||||
|
|
||||||
final TestResults testResults = new TestResults();
|
final TestResult testResult = new TestResult();
|
||||||
|
|
||||||
DatagramListener listener = new DatagramListener() {
|
DatagramListener listener = new DatagramListener() {
|
||||||
public boolean datagramReceived(DatagramPacket datagramPacket) {
|
public boolean datagramReceived(DatagramPacket datagramPacket) {
|
||||||
if (datagramPacket.getAddress().equals(address) && datagramPacket.getPort() == port) {
|
if (datagramPacket.getAddress().equals(address) && datagramPacket.getPort() == port) {
|
||||||
if (Arrays.equals(datagramPacket.getData(), password)) {
|
if (Arrays.equals(datagramPacket.getData(), password)) {
|
||||||
testResults.setResult(true);
|
testResult.setResult(true);
|
||||||
ended = true;
|
ended = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testResults.setResult(false);
|
|
||||||
ended = true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -765,7 +769,59 @@ public abstract class TransportCandidate {
|
||||||
|
|
||||||
this.removeListener(listener);
|
this.removeListener(listener);
|
||||||
|
|
||||||
return testResults.isReachable();
|
return testResult.isReachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testASync(final InetAddress address, final int port) {
|
||||||
|
|
||||||
|
Thread thread = new Thread(new Runnable() {
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
DatagramListener listener = new DatagramListener() {
|
||||||
|
public boolean datagramReceived(DatagramPacket datagramPacket) {
|
||||||
|
if (datagramPacket.getAddress().equals(address) && datagramPacket.getPort() == port) {
|
||||||
|
if (Arrays.equals(datagramPacket.getData(), password)) {
|
||||||
|
TestResult testResult = new TestResult();
|
||||||
|
testResult.setResult(true);
|
||||||
|
fireTestResult(testResult);
|
||||||
|
ended = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
addListener(listener);
|
||||||
|
|
||||||
|
DatagramPacket packet = new DatagramPacket(password, password.length);
|
||||||
|
|
||||||
|
packet.setAddress(address);
|
||||||
|
packet.setPort(port);
|
||||||
|
|
||||||
|
long delay = 200;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < tries; i++) {
|
||||||
|
socket.send(packet);
|
||||||
|
if (ended) break;
|
||||||
|
try {
|
||||||
|
Thread.sleep(delay);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Do Nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
removeListener(listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addListener(DatagramListener listener) {
|
public void addListener(DatagramListener listener) {
|
||||||
|
@ -776,17 +832,12 @@ public abstract class TransportCandidate {
|
||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TestResults {
|
public void addResultListener(ResultListener resultListener) {
|
||||||
|
resultListeners.add(resultListener);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean result=false;
|
public void removeResultListener(ResultListener resultListener) {
|
||||||
|
resultListeners.remove(resultListener);
|
||||||
public boolean isReachable() {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResult(boolean result) {
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
|
|
||||||
// The time we give to the candidates check before we accept or decline the
|
// The time we give to the candidates check before we accept or decline the
|
||||||
// transport (in milliseconds)
|
// transport (in milliseconds)
|
||||||
public final static int CANDIDATES_ACCEPT_PERIOD = 3000;
|
public final static int CANDIDATES_ACCEPT_PERIOD = 4000;
|
||||||
|
|
||||||
// The session this nenotiator belongs to
|
// The session this nenotiator belongs to
|
||||||
private final JingleSession session;
|
private final JingleSession session;
|
||||||
|
@ -69,6 +69,9 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
// Valid remote candidates
|
// Valid remote candidates
|
||||||
private final List<TransportCandidate> validRemoteCandidates = new ArrayList<TransportCandidate>();
|
private final List<TransportCandidate> validRemoteCandidates = new ArrayList<TransportCandidate>();
|
||||||
|
|
||||||
|
// Accepted Remote Candidates
|
||||||
|
private final List<TransportCandidate> acceptedRemoteCandidates = new ArrayList<TransportCandidate>();
|
||||||
|
|
||||||
// The best local candidate we have offered (and accepted by the other part)
|
// The best local candidate we have offered (and accepted by the other part)
|
||||||
private TransportCandidate acceptedLocalCandidate;
|
private TransportCandidate acceptedLocalCandidate;
|
||||||
|
|
||||||
|
@ -165,10 +168,6 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
public void close() {
|
public void close() {
|
||||||
super.close();
|
super.close();
|
||||||
|
|
||||||
for (TransportCandidate candidate : offeredCandidates)
|
|
||||||
if (candidate.getCandidateEcho() != null)
|
|
||||||
candidate.removeCandidateEcho();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TransportCandidate> getOfferedCandidates() {
|
public List<TransportCandidate> getOfferedCandidates() {
|
||||||
|
@ -283,10 +282,10 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
|
|
||||||
// Sleep for some time, waiting for the candidates checks
|
// Sleep for some time, waiting for the candidates checks
|
||||||
|
|
||||||
int totalTime = (CANDIDATES_ACCEPT_PERIOD + (TransportResolver.CHECK_TIMEOUT * (resolver.getCandidatesList().size() + 1)));
|
int totalTime = (CANDIDATES_ACCEPT_PERIOD + TransportResolver.CHECK_TIMEOUT);
|
||||||
int tries = (int) Math.ceil(totalTime / 1000);
|
int tries = (int) Math.ceil(totalTime / 1000);
|
||||||
|
|
||||||
for (int i = 0; i < tries; i++) {
|
for (int i = 0; i < tries - 2; i++) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
}
|
}
|
||||||
|
@ -301,18 +300,64 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
|
|
||||||
if (bestRemote != null && (state == pending || state == active)) {
|
if (bestRemote != null && (state == pending || state == active)) {
|
||||||
// Accepting the remote candidate
|
// Accepting the remote candidate
|
||||||
Jingle jout = new Jingle(Jingle.Action.TRANSPORTACCEPT);
|
if (!acceptedRemoteCandidates.contains(bestRemote)) {
|
||||||
jout.addTransport(getJingleTransport(bestRemote));
|
Jingle jout = new Jingle(Jingle.Action.TRANSPORTACCEPT);
|
||||||
|
jout.addTransport(getJingleTransport(bestRemote));
|
||||||
// Send the packet
|
|
||||||
js.sendFormattedJingle(jin, jout);
|
|
||||||
|
|
||||||
|
// Send the packet
|
||||||
|
js.sendFormattedJingle(jin, jout);
|
||||||
|
acceptedRemoteCandidates.add(bestRemote);
|
||||||
|
}
|
||||||
if (isEstablished()) {
|
if (isEstablished()) {
|
||||||
setState(active);
|
setState(active);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Once we are in pending state, look for any valid remote
|
||||||
|
// candidate, and send an "accept" if we have one...
|
||||||
|
TransportCandidate bestRemote = getBestRemoteCandidate();
|
||||||
|
|
||||||
|
if (bestRemote == null) {
|
||||||
|
for (TransportCandidate candidate : remoteCandidates) {
|
||||||
|
if (candidate instanceof ICECandidate) {
|
||||||
|
ICECandidate iceCandidate = (ICECandidate) candidate;
|
||||||
|
if (iceCandidate.getType().equals("relay")) {
|
||||||
|
//TODO Check if the relay is reacheable
|
||||||
|
addValidRemoteCandidate(iceCandidate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
bestRemote = getBestRemoteCandidate();
|
||||||
|
State state = getState();
|
||||||
|
if (bestRemote != null && (state == pending || state == active)) {
|
||||||
|
if (!acceptedRemoteCandidates.contains(bestRemote)) {
|
||||||
|
Jingle jout = new Jingle(Jingle.Action.TRANSPORTACCEPT);
|
||||||
|
jout.addTransport(getJingleTransport(bestRemote));
|
||||||
|
|
||||||
|
// Send the packet
|
||||||
|
js.sendFormattedJingle(jin, jout);
|
||||||
|
acceptedRemoteCandidates.add(bestRemote);
|
||||||
|
}
|
||||||
|
if (isEstablished()) {
|
||||||
|
setState(active);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (getState() == null || !getState().equals(active)) {
|
if (getState() == null || !getState().equals(active)) {
|
||||||
try {
|
try {
|
||||||
session.terminate();
|
session.terminate();
|
||||||
|
@ -698,9 +743,7 @@ public abstract class TransportNegotiator extends JingleNegotiator {
|
||||||
setAcceptedLocalCandidate(cand);
|
setAcceptedLocalCandidate(cand);
|
||||||
|
|
||||||
if (isEstablished()) {
|
if (isEstablished()) {
|
||||||
|
|
||||||
System.out.println("SET ACTIVE");
|
System.out.println("SET ACTIVE");
|
||||||
|
|
||||||
setState(active);
|
setState(active);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public abstract class TransportResolver {
|
||||||
public Type type = Type.rawupd;
|
public Type type = Type.rawupd;
|
||||||
|
|
||||||
// the time, in milliseconds, before a check aborts
|
// the time, in milliseconds, before a check aborts
|
||||||
public static final int CHECK_TIMEOUT = 4000;
|
public static final int CHECK_TIMEOUT = 5000;
|
||||||
|
|
||||||
// Listeners for events
|
// Listeners for events
|
||||||
private final ArrayList<TransportResolverListener> listeners = new ArrayList<TransportResolverListener>();
|
private final ArrayList<TransportResolverListener> listeners = new ArrayList<TransportResolverListener>();
|
||||||
|
|
Loading…
Reference in a new issue