initWithInvite method
Future<void>
initWithInvite(
- CallType type,
- RTCSessionDescription offer,
- SDPStreamMetadata? metadata,
- int lifetime,
- bool isGroupCall,
Implementation
Future<void> initWithInvite(CallType type, RTCSessionDescription offer,
SDPStreamMetadata? metadata, int lifetime, bool isGroupCall) async {
if (!isGroupCall) {
// glare fixes
final prevCallId = voip.incomingCallRoomId[room.id];
if (prevCallId != null) {
// This is probably an outbound call, but we already have a incoming invite, so let's terminate it.
final prevCall = voip.calls[prevCallId];
if (prevCall != null) {
if (prevCall.inviteOrAnswerSent) {
Logs().d('[glare] invite or answer sent, lex compare now');
if (callId.compareTo(prevCall.callId) > 0) {
Logs().d(
'[glare] new call $callId needs to be canceled because the older one ${prevCall.callId} has a smaller lex');
await hangup();
return;
} else {
Logs().d(
'[glare] nice, lex of newer call $callId is smaller auto accept this here');
/// These fixes do not work all the time because sometimes the code
/// is at an unrecoverable stage (invite already sent when we were
/// checking if we want to send a invite), so commented out answering
/// automatically to prevent unknown cases
// await answer();
// return;
}
} else {
Logs().d(
'[glare] ${prevCall.callId} was still preparing prev call, nvm now cancel it');
await prevCall.hangup();
}
}
}
}
await _preparePeerConnection();
if (metadata != null) {
_updateRemoteSDPStreamMetadata(metadata);
}
await pc!.setRemoteDescription(offer);
/// only add local stream if it is not a group call.
if (!isGroupCall) {
final stream = await _getUserMedia(type);
if (stream != null) {
await addLocalStream(stream, SDPStreamMetadataPurpose.Usermedia);
} else {
// we don't have a localstream, call probably crashed
// for sanity
if (state == CallState.kEnded) {
return;
}
}
}
setCallState(CallState.kRinging);
ringingTimer = Timer(Duration(seconds: 30), () {
if (state == CallState.kRinging) {
Logs().v('[VOIP] Call invite has expired. Hanging up.');
hangupParty = CallParty.kRemote; // effectively
fireCallEvent(CallEvent.kHangup);
hangup(CallErrorCode.InviteTimeout);
}
ringingTimer?.cancel();
ringingTimer = null;
});
}