@@ -54,7 +54,6 @@ import javax.net.ssl.X509TrustManager;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.R;
-import eu.siacs.conversations.crypto.DomainHostnameVerifier;
import eu.siacs.conversations.crypto.XmppDomainVerifier;
import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.crypto.sasl.Anonymous;
@@ -311,7 +311,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
restartContentMap = existing.modifiedCredentials(newCredentials, IceUdpTransportInfo.Setup.ACTPASS);
} else {
final IceUdpTransportInfo.Setup setup = getPeerDtlsSetup();
- Log.d(Config.LOGTAG, "received confirmation of ICE restart" + newCredentials.values()+" peer_setup="+setup);
+ Log.d(Config.LOGTAG, "received confirmation of ICE restart" + newCredentials.values() + " peer_setup=" + setup);
// DTLS setup attribute needs to be rewritten to reflect current peer state
// https://groups.google.com/g/discuss-webrtc/c/DfpIMwvUfeM
restartContentMap = existing.modifiedCredentials(newCredentials, setup);
@@ -319,12 +319,18 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
if (applyIceRestart(jinglePacket, restartContentMap, isOffer)) {
return isOffer;
} else {
+ Log.d(Config.LOGTAG,"ignored ice restart. offer="+isOffer);
respondWithTieBreak(jinglePacket);
return true;
}
} catch (final Exception exception) {
respondOk(jinglePacket);
final Throwable rootCause = Throwables.getRootCause(exception);
+ if (rootCause instanceof WebRTCWrapper.PeerConnectionNotInitialized) {
+ Log.d(Config.LOGTAG,"ignoring PeerConnectionNotInitialized");
+ //TODO donβt respond OK but respond with out-of-order
+ return true;
+ }
Log.d(Config.LOGTAG, "failure to apply ICE restart", rootCause);
webRTCWrapper.close();
sendSessionTerminate(Reason.ofThrowable(rootCause), rootCause.getMessage());
@@ -1466,21 +1472,18 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
}
final boolean neverConnected = !this.stateHistory.contains(PeerConnection.PeerConnectionState.CONNECTED);
- final boolean failedOrDisconnected = Arrays.asList(
- PeerConnection.PeerConnectionState.FAILED,
- PeerConnection.PeerConnectionState.DISCONNECTED
- ).contains(newState);
-
- if (neverConnected && failedOrDisconnected) {
- if (isTerminated()) {
- Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not sending session-terminate after connectivity error because session is already in state " + this.state);
+ if (newState == PeerConnection.PeerConnectionState.FAILED) {
+ if (neverConnected) {
+ if (isTerminated()) {
+ Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": not sending session-terminate after connectivity error because session is already in state " + this.state);
+ return;
+ }
+ webRTCWrapper.execute(this::closeWebRTCSessionAfterFailedConnection);
return;
+ } else {
+ webRTCWrapper.restartIce();
}
- webRTCWrapper.execute(this::closeWebRTCSessionAfterFailedConnection);
- } else if (newState == PeerConnection.PeerConnectionState.FAILED) {
- Log.d(Config.LOGTAG, "attempting to restart ICE");
- webRTCWrapper.restartIce();
}
updateEndUserState();
}
@@ -1491,6 +1494,7 @@ public class JingleRtpConnection extends AbstractJingleConnection implements Web
}
private void initiateIceRestart() {
+ this.stateHistory.clear();
this.webRTCWrapper.setIsReadyToReceiveIceCandidates(false);
final SessionDescription sessionDescription;
try {
@@ -431,7 +431,7 @@ public class WebRTCWrapper {
videoTrack.setEnabled(enabled);
}
- ListenableFuture<SessionDescription> setLocalDescription() {
+ synchronized ListenableFuture<SessionDescription> setLocalDescription() {
return Futures.transformAsync(getPeerConnectionFuture(), peerConnection -> {
final SettableFuture<SessionDescription> future = SettableFuture.create();
peerConnection.setLocalDescription(new SetSdpObserver() {
@@ -458,7 +458,7 @@ public class WebRTCWrapper {
}
}
- ListenableFuture<Void> setRemoteDescription(final SessionDescription sessionDescription) {
+ synchronized ListenableFuture<Void> setRemoteDescription(final SessionDescription sessionDescription) {
Log.d(EXTENDED_LOGGING_TAG, "setting remote description:");
logDescription(sessionDescription);
return Futures.transformAsync(getPeerConnectionFuture(), peerConnection -> {
@@ -482,12 +482,20 @@ public class WebRTCWrapper {
private ListenableFuture<PeerConnection> getPeerConnectionFuture() {
final PeerConnection peerConnection = this.peerConnection;
if (peerConnection == null) {
- return Futures.immediateFailedFuture(new IllegalStateException("initialize PeerConnection first"));
+ return Futures.immediateFailedFuture(new PeerConnectionNotInitialized());
} else {
return Futures.immediateFuture(peerConnection);
}
}
+ private PeerConnection requirePeerConnection() {
+ final PeerConnection peerConnection = this.peerConnection;
+ if (peerConnection == null) {
+ throw new PeerConnectionNotInitialized();
+ }
+ return peerConnection;
+ }
+
void addIceCandidate(IceCandidate iceCandidate) {
requirePeerConnection().addIceCandidate(iceCandidate);
}
@@ -512,10 +520,15 @@ public class WebRTCWrapper {
}
}
- public PeerConnection.PeerConnectionState getState() {
+ PeerConnection.PeerConnectionState getState() {
return requirePeerConnection().connectionState();
}
+ public PeerConnection.SignalingState getSignalingState() {
+ return requirePeerConnection().signalingState();
+ }
+
+
EglBase.Context getEglBaseContext() {
return this.eglBase.getEglBaseContext();
}
@@ -528,14 +541,6 @@ public class WebRTCWrapper {
return Optional.fromNullable(this.remoteVideoTrack);
}
- private PeerConnection requirePeerConnection() {
- final PeerConnection peerConnection = this.peerConnection;
- if (peerConnection == null) {
- throw new PeerConnectionNotInitialized();
- }
- return peerConnection;
- }
-
private Context requireContext() {
final Context context = this.context;
if (context == null) {
@@ -552,10 +557,6 @@ public class WebRTCWrapper {
executorService.execute(command);
}
- public PeerConnection.SignalingState getSignalingState() {
- return requirePeerConnection().signalingState();
- }
-
public interface EventCallback {
void onIceCandidate(IceCandidate iceCandidate);