fix: ice restart mechanism

This commit is contained in:
td 2024-05-13 22:07:38 +05:30
parent 9cc7c0e581
commit 59703aef75
No known key found for this signature in database
GPG Key ID: 62A30523D4D6CE28
1 changed files with 16 additions and 25 deletions

View File

@ -519,14 +519,6 @@ class CallSession {
_remoteCandidates.add(candidate); _remoteCandidates.add(candidate);
} }
} }
if (pc != null &&
{
RTCIceConnectionState.RTCIceConnectionStateDisconnected,
RTCIceConnectionState.RTCIceConnectionStateFailed
}.contains(pc!.iceConnectionState)) {
await restartIce();
}
} }
void onAssertedIdentityReceived(AssertedIdentity identity) { void onAssertedIdentityReceived(AssertedIdentity identity) {
@ -566,7 +558,6 @@ class CallSession {
return true; return true;
} catch (err) { } catch (err) {
fireCallEvent(CallStateChange.kError); fireCallEvent(CallStateChange.kError);
return false; return false;
} }
} else { } else {
@ -1087,7 +1078,7 @@ class CallSession {
} }
Future<void> onNegotiationNeeded() async { Future<void> onNegotiationNeeded() async {
Logs().i('Negotiation is needed!'); Logs().d('Negotiation is needed!');
_makingOffer = true; _makingOffer = true;
try { try {
// The first addTrack(audio track) on iOS will trigger // The first addTrack(audio track) on iOS will trigger
@ -1106,13 +1097,14 @@ class CallSession {
} }
Future<void> _preparePeerConnection() async { Future<void> _preparePeerConnection() async {
int iceRestartedCount = 0;
try { try {
pc = await _createPeerConnection(); pc = await _createPeerConnection();
pc!.onRenegotiationNeeded = onNegotiationNeeded; pc!.onRenegotiationNeeded = onNegotiationNeeded;
pc!.onIceCandidate = (RTCIceCandidate candidate) async { pc!.onIceCandidate = (RTCIceCandidate candidate) async {
if (callHasEnded) return; if (callHasEnded) return;
//Logs().v('[VOIP] onIceCandidate => ${candidate.toMap().toString()}');
_localCandidates.add(candidate); _localCandidates.add(candidate);
if (state == CallState.kRinging || !_inviteOrAnswerSent) return; if (state == CallState.kRinging || !_inviteOrAnswerSent) return;
@ -1149,12 +1141,21 @@ class CallSession {
if (state == RTCIceConnectionState.RTCIceConnectionStateConnected) { if (state == RTCIceConnectionState.RTCIceConnectionStateConnected) {
_localCandidates.clear(); _localCandidates.clear();
_remoteCandidates.clear(); _remoteCandidates.clear();
iceRestartedCount = 0;
setCallState(CallState.kConnected); setCallState(CallState.kConnected);
// fix any state/race issues we had with sdp packets and cloned streams // fix any state/race issues we had with sdp packets and cloned streams
await updateMuteStatus(); await updateMuteStatus();
_missedCall = false; _missedCall = false;
} else if (state == RTCIceConnectionState.RTCIceConnectionStateFailed) { } else if ({
await hangup(reason: CallErrorCode.iceFailed); RTCIceConnectionState.RTCIceConnectionStateFailed,
RTCIceConnectionState.RTCIceConnectionStateDisconnected
}.contains(state)) {
if (iceRestartedCount < 3) {
await restartIce();
iceRestartedCount++;
} else {
await hangup(reason: CallErrorCode.iceFailed);
}
} }
}; };
} catch (e) { } catch (e) {
@ -1234,10 +1235,8 @@ class CallSession {
Logs().v('[VOIP] iceRestart.'); Logs().v('[VOIP] iceRestart.');
// Needs restart ice on session.pc and renegotiation. // Needs restart ice on session.pc and renegotiation.
_iceGatheringFinished = false; _iceGatheringFinished = false;
final desc =
await pc!.createOffer(_getOfferAnswerConstraints(iceRestart: true));
await pc!.setLocalDescription(desc);
_localCandidates.clear(); _localCandidates.clear();
await pc!.restartIce();
} }
Future<MediaStream?> _getUserMedia(CallType type) async { Future<MediaStream?> _getUserMedia(CallType type) async {
@ -1272,8 +1271,7 @@ class CallSession {
}; };
final pc = await voip.delegate.createPeerConnection(configuration); final pc = await voip.delegate.createPeerConnection(configuration);
pc.onTrack = (RTCTrackEvent event) async { pc.onTrack = (RTCTrackEvent event) async {
if (event.streams.isNotEmpty) { for (final stream in event.streams) {
final stream = event.streams[0];
await _addRemoteStream(stream); await _addRemoteStream(stream);
for (final track in stream.getTracks()) { for (final track in stream.getTracks()) {
track.onEnded = () async { track.onEnded = () async {
@ -1322,13 +1320,6 @@ class CallSession {
await wpstream.dispose(); await wpstream.dispose();
} }
Map<String, dynamic> _getOfferAnswerConstraints({bool iceRestart = false}) {
return {
'mandatory': {if (iceRestart) 'IceRestart': true},
'optional': [],
};
}
Future<void> _sendCandidateQueue() async { Future<void> _sendCandidateQueue() async {
if (callHasEnded) return; if (callHasEnded) return;
/* /*