fix: check negotiate party and call ids
chore: making some call naming schemes better
This commit is contained in:
parent
0bb1e3bef9
commit
520dfdbe3e
|
|
@ -30,18 +30,18 @@ import 'package:matrix/src/utils/cached_stream_controller.dart';
|
||||||
/// version 1
|
/// version 1
|
||||||
const String voipProtoVersion = '1';
|
const String voipProtoVersion = '1';
|
||||||
|
|
||||||
class Timeouts {
|
class CallTimeouts {
|
||||||
/// The default life time for call events, in millisecond.
|
/// The default life time for call events, in millisecond.
|
||||||
static const lifetimeMs = 10 * 1000;
|
static const defaultCallEventLifetime = Duration(seconds: 10);
|
||||||
|
|
||||||
/// The length of time a call can be ringing for.
|
/// The length of time a call can be ringing for.
|
||||||
static const callTimeoutSec = 60;
|
static const callInviteLifetime = Duration(seconds: 60);
|
||||||
|
|
||||||
/// The delay for ice gathering.
|
/// The delay for ice gathering.
|
||||||
static const iceGatheringDelayMs = 200;
|
static const iceGatheringDelay = Duration(milliseconds: 200);
|
||||||
|
|
||||||
/// Delay before createOffer.
|
/// Delay before createOffer.
|
||||||
static const delayBeforeOfferMs = 100;
|
static const delayBeforeOffer = Duration(milliseconds: 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RTCIceCandidateExt on RTCIceCandidate {
|
extension RTCIceCandidateExt on RTCIceCandidate {
|
||||||
|
|
@ -504,7 +504,7 @@ class CallSession {
|
||||||
|
|
||||||
setCallState(CallState.kRinging);
|
setCallState(CallState.kRinging);
|
||||||
|
|
||||||
ringingTimer = Timer(Duration(seconds: 30), () {
|
ringingTimer = Timer(CallTimeouts.callInviteLifetime, () {
|
||||||
if (state == CallState.kRinging) {
|
if (state == CallState.kRinging) {
|
||||||
Logs().v('[VOIP] Call invite has expired. Hanging up.');
|
Logs().v('[VOIP] Call invite has expired. Hanging up.');
|
||||||
hangupParty = CallParty.kRemote; // effectively
|
hangupParty = CallParty.kRemote; // effectively
|
||||||
|
|
@ -621,8 +621,7 @@ class CallSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send select_answer event.
|
/// Send select_answer event.
|
||||||
await sendSelectCallAnswer(
|
await sendSelectCallAnswer(opts.room, callId, localPartyId, remotePartyId!);
|
||||||
opts.room, callId, Timeouts.lifetimeMs, localPartyId, remotePartyId!);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> onNegotiateReceived(
|
Future<void> onNegotiateReceived(
|
||||||
|
|
@ -659,7 +658,11 @@ class CallSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
await sendCallNegotiate(
|
await sendCallNegotiate(
|
||||||
room, callId, Timeouts.lifetimeMs, localPartyId, answer.sdp!,
|
room,
|
||||||
|
callId,
|
||||||
|
CallTimeouts.defaultCallEventLifetime.inMilliseconds,
|
||||||
|
localPartyId,
|
||||||
|
answer.sdp!,
|
||||||
type: answer.type!);
|
type: answer.type!);
|
||||||
await pc!.setLocalDescription(answer);
|
await pc!.setLocalDescription(answer);
|
||||||
}
|
}
|
||||||
|
|
@ -983,7 +986,7 @@ class CallSession {
|
||||||
if (localUserMediaStream != null && localUserMediaStream!.stream != null) {
|
if (localUserMediaStream != null && localUserMediaStream!.stream != null) {
|
||||||
final stream = await _getUserMedia(CallType.kVideo);
|
final stream = await _getUserMedia(CallType.kVideo);
|
||||||
if (stream != null) {
|
if (stream != null) {
|
||||||
Logs().e('[VOIP] running replaceTracks() on stream: ${stream.id}');
|
Logs().d('[VOIP] running replaceTracks() on stream: ${stream.id}');
|
||||||
_setTracksEnabled(stream.getVideoTracks(), true);
|
_setTracksEnabled(stream.getVideoTracks(), true);
|
||||||
// replace local tracks
|
// replace local tracks
|
||||||
for (final track in localUserMediaStream!.stream!.getTracks()) {
|
for (final track in localUserMediaStream!.stream!.getTracks()) {
|
||||||
|
|
@ -1145,8 +1148,7 @@ class CallSession {
|
||||||
Logs().d('[VOIP] Rejecting call: $callId');
|
Logs().d('[VOIP] Rejecting call: $callId');
|
||||||
await terminate(CallParty.kLocal, CallErrorCode.UserHangup, shouldEmit);
|
await terminate(CallParty.kLocal, CallErrorCode.UserHangup, shouldEmit);
|
||||||
if (shouldEmit) {
|
if (shouldEmit) {
|
||||||
await sendCallReject(
|
await sendCallReject(room, callId, localPartyId, reason);
|
||||||
room, callId, Timeouts.lifetimeMs, localPartyId, reason);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1257,8 +1259,7 @@ class CallSession {
|
||||||
if (pc!.iceGatheringState ==
|
if (pc!.iceGatheringState ==
|
||||||
RTCIceGatheringState.RTCIceGatheringStateGathering) {
|
RTCIceGatheringState.RTCIceGatheringStateGathering) {
|
||||||
// Allow a short time for initial candidates to be gathered
|
// Allow a short time for initial candidates to be gathered
|
||||||
await Future.delayed(
|
await Future.delayed(CallTimeouts.iceGatheringDelay);
|
||||||
Duration(milliseconds: Timeouts.iceGatheringDelayMs));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callHasEnded) return;
|
if (callHasEnded) return;
|
||||||
|
|
@ -1271,8 +1272,14 @@ class CallSession {
|
||||||
Logs().d('[glare] new invite sent about to be called');
|
Logs().d('[glare] new invite sent about to be called');
|
||||||
|
|
||||||
await sendInviteToCall(
|
await sendInviteToCall(
|
||||||
room, callId, Timeouts.lifetimeMs, localPartyId, null, offer.sdp!,
|
room,
|
||||||
capabilities: callCapabilities, metadata: metadata);
|
callId,
|
||||||
|
CallTimeouts.callInviteLifetime.inMilliseconds,
|
||||||
|
localPartyId,
|
||||||
|
null,
|
||||||
|
offer.sdp!,
|
||||||
|
capabilities: callCapabilities,
|
||||||
|
metadata: metadata);
|
||||||
// just incase we ended the call but already sent the invite
|
// just incase we ended the call but already sent the invite
|
||||||
if (state == CallState.kEnded) {
|
if (state == CallState.kEnded) {
|
||||||
await hangup(CallErrorCode.Replaced, false);
|
await hangup(CallErrorCode.Replaced, false);
|
||||||
|
|
@ -1287,7 +1294,7 @@ class CallSession {
|
||||||
|
|
||||||
setCallState(CallState.kInviteSent);
|
setCallState(CallState.kInviteSent);
|
||||||
|
|
||||||
inviteTimer = Timer(Duration(seconds: Timeouts.callTimeoutSec), () {
|
inviteTimer = Timer(CallTimeouts.callInviteLifetime, () {
|
||||||
if (state == CallState.kInviteSent) {
|
if (state == CallState.kInviteSent) {
|
||||||
hangup(CallErrorCode.InviteTimeout);
|
hangup(CallErrorCode.InviteTimeout);
|
||||||
}
|
}
|
||||||
|
|
@ -1296,7 +1303,11 @@ class CallSession {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await sendCallNegotiate(
|
await sendCallNegotiate(
|
||||||
room, callId, Timeouts.lifetimeMs, localPartyId, offer.sdp!,
|
room,
|
||||||
|
callId,
|
||||||
|
CallTimeouts.defaultCallEventLifetime.inMilliseconds,
|
||||||
|
localPartyId,
|
||||||
|
offer.sdp!,
|
||||||
type: offer.type!,
|
type: offer.type!,
|
||||||
capabilities: callCapabilities,
|
capabilities: callCapabilities,
|
||||||
metadata: metadata);
|
metadata: metadata);
|
||||||
|
|
@ -1311,7 +1322,7 @@ class CallSession {
|
||||||
// onNegotiationNeeded, which causes creatOffer to only include
|
// onNegotiationNeeded, which causes creatOffer to only include
|
||||||
// audio m-line, add delay and wait for video track to be added,
|
// audio m-line, add delay and wait for video track to be added,
|
||||||
// then createOffer can get audio/video m-line correctly.
|
// then createOffer can get audio/video m-line correctly.
|
||||||
await Future.delayed(Duration(milliseconds: Timeouts.delayBeforeOfferMs));
|
await Future.delayed(CallTimeouts.delayBeforeOffer);
|
||||||
final offer = await pc!.createOffer({});
|
final offer = await pc!.createOffer({});
|
||||||
await _gotLocalOffer(offer);
|
await _gotLocalOffer(offer);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -1703,8 +1714,8 @@ class CallSession {
|
||||||
/// [version] is the version of the VoIP specification this message adheres to. This specification is version 1.
|
/// [version] is the version of the VoIP specification this message adheres to. This specification is version 1.
|
||||||
/// [party_id] The party ID for call, Can be set to client.deviceId.
|
/// [party_id] The party ID for call, Can be set to client.deviceId.
|
||||||
/// [selected_party_id] The party ID for the selected answer.
|
/// [selected_party_id] The party ID for the selected answer.
|
||||||
Future<String?> sendSelectCallAnswer(Room room, String callId, int lifetime,
|
Future<String?> sendSelectCallAnswer(
|
||||||
String party_id, String selected_party_id,
|
Room room, String callId, String party_id, String selected_party_id,
|
||||||
{String version = voipProtoVersion, String? txid}) async {
|
{String version = voipProtoVersion, String? txid}) async {
|
||||||
txid ??= 'txid${DateTime.now().millisecondsSinceEpoch}';
|
txid ??= 'txid${DateTime.now().millisecondsSinceEpoch}';
|
||||||
|
|
||||||
|
|
@ -1713,7 +1724,6 @@ class CallSession {
|
||||||
'party_id': party_id,
|
'party_id': party_id,
|
||||||
if (groupCallId != null) 'conf_id': groupCallId,
|
if (groupCallId != null) 'conf_id': groupCallId,
|
||||||
'version': version,
|
'version': version,
|
||||||
'lifetime': lifetime,
|
|
||||||
'selected_party_id': selected_party_id,
|
'selected_party_id': selected_party_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1730,7 +1740,7 @@ class CallSession {
|
||||||
/// [version] is the version of the VoIP specification this message adheres to. This specification is version 1.
|
/// [version] is the version of the VoIP specification this message adheres to. This specification is version 1.
|
||||||
/// [party_id] The party ID for call, Can be set to client.deviceId.
|
/// [party_id] The party ID for call, Can be set to client.deviceId.
|
||||||
Future<String?> sendCallReject(
|
Future<String?> sendCallReject(
|
||||||
Room room, String callId, int lifetime, String party_id, String? reason,
|
Room room, String callId, String party_id, String? reason,
|
||||||
{String version = voipProtoVersion, String? txid}) async {
|
{String version = voipProtoVersion, String? txid}) async {
|
||||||
txid ??= 'txid${DateTime.now().millisecondsSinceEpoch}';
|
txid ??= 'txid${DateTime.now().millisecondsSinceEpoch}';
|
||||||
|
|
||||||
|
|
@ -1740,7 +1750,6 @@ class CallSession {
|
||||||
if (groupCallId != null) 'conf_id': groupCallId,
|
if (groupCallId != null) 'conf_id': groupCallId,
|
||||||
if (reason != null) 'reason': reason,
|
if (reason != null) 'reason': reason,
|
||||||
'version': version,
|
'version': version,
|
||||||
'lifetime': lifetime,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return await _sendContent(
|
return await _sendContent(
|
||||||
|
|
@ -1972,6 +1981,9 @@ class CallSession {
|
||||||
}) async {
|
}) async {
|
||||||
txid ??= client.generateUniqueTransactionId();
|
txid ??= client.generateUniqueTransactionId();
|
||||||
final mustEncrypt = room.encrypted && client.encryptionEnabled;
|
final mustEncrypt = room.encrypted && client.encryptionEnabled;
|
||||||
|
|
||||||
|
// opponentDeviceId is only set for a few events during group calls,
|
||||||
|
// therefore only group calls use to-device messages for some events
|
||||||
if (opponentDeviceId != null) {
|
if (opponentDeviceId != null) {
|
||||||
final toDeviceSeq = this.toDeviceSeq++;
|
final toDeviceSeq = this.toDeviceSeq++;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ class GroupCall {
|
||||||
WrappedMediaStream? localUserMediaStream;
|
WrappedMediaStream? localUserMediaStream;
|
||||||
WrappedMediaStream? localScreenshareStream;
|
WrappedMediaStream? localScreenshareStream;
|
||||||
String? localDesktopCapturerSourceId;
|
String? localDesktopCapturerSourceId;
|
||||||
List<CallSession> calls = [];
|
List<CallSession> callSessions = [];
|
||||||
List<User> participants = [];
|
List<User> participants = [];
|
||||||
List<WrappedMediaStream> userMediaStreams = [];
|
List<WrappedMediaStream> userMediaStreams = [];
|
||||||
List<WrappedMediaStream> screenshareStreams = [];
|
List<WrappedMediaStream> screenshareStreams = [];
|
||||||
|
|
@ -404,7 +404,7 @@ class GroupCall {
|
||||||
final stream =
|
final stream =
|
||||||
await voip.delegate.mediaDevices.getUserMedia({'audio': true});
|
await voip.delegate.mediaDevices.getUserMedia({'audio': true});
|
||||||
final audioTrack = stream.getAudioTracks().first;
|
final audioTrack = stream.getAudioTracks().first;
|
||||||
for (final call in calls) {
|
for (final call in callSessions) {
|
||||||
await call.updateAudioDevice(audioTrack);
|
await call.updateAudioDevice(audioTrack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -441,7 +441,7 @@ class GroupCall {
|
||||||
|
|
||||||
_callSubscription = voip.onIncomingCall.stream.listen(onIncomingCall);
|
_callSubscription = voip.onIncomingCall.stream.listen(onIncomingCall);
|
||||||
|
|
||||||
for (final call in calls) {
|
for (final call in callSessions) {
|
||||||
await onIncomingCall(call);
|
await onIncomingCall(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -478,7 +478,7 @@ class GroupCall {
|
||||||
|
|
||||||
await removeMemberStateEvent();
|
await removeMemberStateEvent();
|
||||||
|
|
||||||
final callsCopy = calls.toList();
|
final callsCopy = callSessions.toList();
|
||||||
|
|
||||||
for (final call in callsCopy) {
|
for (final call in callsCopy) {
|
||||||
await removeCall(call, CallErrorCode.UserHangup);
|
await removeCall(call, CallErrorCode.UserHangup);
|
||||||
|
|
@ -553,7 +553,7 @@ class GroupCall {
|
||||||
setTracksEnabled(localUserMediaStream!.stream!.getAudioTracks(), !muted);
|
setTracksEnabled(localUserMediaStream!.stream!.getAudioTracks(), !muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final call in calls) {
|
for (final call in callSessions) {
|
||||||
await call.setMicrophoneMuted(muted);
|
await call.setMicrophoneMuted(muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -571,7 +571,7 @@ class GroupCall {
|
||||||
setTracksEnabled(localUserMediaStream!.stream!.getVideoTracks(), !muted);
|
setTracksEnabled(localUserMediaStream!.stream!.getVideoTracks(), !muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final call in calls) {
|
for (final call in callSessions) {
|
||||||
await call.setLocalVideoMuted(muted);
|
await call.setLocalVideoMuted(muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -620,7 +620,7 @@ class GroupCall {
|
||||||
await localScreenshareStream!.initialize();
|
await localScreenshareStream!.initialize();
|
||||||
|
|
||||||
onGroupCallEvent.add(GroupCallEvent.LocalScreenshareStateChanged);
|
onGroupCallEvent.add(GroupCallEvent.LocalScreenshareStateChanged);
|
||||||
for (final call in calls) {
|
for (final call in callSessions) {
|
||||||
await call.addLocalStream(
|
await call.addLocalStream(
|
||||||
await localScreenshareStream!.stream!.clone(),
|
await localScreenshareStream!.stream!.clone(),
|
||||||
localScreenshareStream!.purpose);
|
localScreenshareStream!.purpose);
|
||||||
|
|
@ -637,7 +637,7 @@ class GroupCall {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (final call in calls) {
|
for (final call in callSessions) {
|
||||||
await call.removeLocalStream(call.localScreenSharingStream!);
|
await call.removeLocalStream(call.localScreenSharingStream!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -935,7 +935,7 @@ class GroupCall {
|
||||||
}
|
}
|
||||||
|
|
||||||
CallSession? getCallByUserId(String userId) {
|
CallSession? getCallByUserId(String userId) {
|
||||||
final value = calls.where((item) => item.remoteUser!.id == userId);
|
final value = callSessions.where((item) => item.remoteUser!.id == userId);
|
||||||
if (value.isNotEmpty) {
|
if (value.isNotEmpty) {
|
||||||
return value.first;
|
return value.first;
|
||||||
}
|
}
|
||||||
|
|
@ -943,7 +943,7 @@ class GroupCall {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> addCall(CallSession call) async {
|
Future<void> addCall(CallSession call) async {
|
||||||
calls.add(call);
|
callSessions.add(call);
|
||||||
await initCall(call);
|
await initCall(call);
|
||||||
onGroupCallEvent.add(GroupCallEvent.CallsChanged);
|
onGroupCallEvent.add(GroupCallEvent.CallsChanged);
|
||||||
}
|
}
|
||||||
|
|
@ -951,14 +951,14 @@ class GroupCall {
|
||||||
Future<void> replaceCall(
|
Future<void> replaceCall(
|
||||||
CallSession existingCall, CallSession replacementCall) async {
|
CallSession existingCall, CallSession replacementCall) async {
|
||||||
final existingCallIndex =
|
final existingCallIndex =
|
||||||
calls.indexWhere((element) => element == existingCall);
|
callSessions.indexWhere((element) => element == existingCall);
|
||||||
|
|
||||||
if (existingCallIndex == -1) {
|
if (existingCallIndex == -1) {
|
||||||
throw Exception('Couldn\'t find call to replace');
|
throw Exception('Couldn\'t find call to replace');
|
||||||
}
|
}
|
||||||
|
|
||||||
calls.removeAt(existingCallIndex);
|
callSessions.removeAt(existingCallIndex);
|
||||||
calls.add(replacementCall);
|
callSessions.add(replacementCall);
|
||||||
|
|
||||||
await disposeCall(existingCall, CallErrorCode.Replaced);
|
await disposeCall(existingCall, CallErrorCode.Replaced);
|
||||||
await initCall(replacementCall);
|
await initCall(replacementCall);
|
||||||
|
|
@ -970,7 +970,7 @@ class GroupCall {
|
||||||
Future<void> removeCall(CallSession call, String hangupReason) async {
|
Future<void> removeCall(CallSession call, String hangupReason) async {
|
||||||
await disposeCall(call, hangupReason);
|
await disposeCall(call, hangupReason);
|
||||||
|
|
||||||
calls.removeWhere((element) => call.callId == element.callId);
|
callSessions.removeWhere((element) => call.callId == element.callId);
|
||||||
|
|
||||||
onGroupCallEvent.add(GroupCallEvent.CallsChanged);
|
onGroupCallEvent.add(GroupCallEvent.CallsChanged);
|
||||||
}
|
}
|
||||||
|
|
@ -1287,7 +1287,7 @@ class GroupCall {
|
||||||
|
|
||||||
onGroupCallEvent.add(GroupCallEvent.ParticipantsChanged);
|
onGroupCallEvent.add(GroupCallEvent.ParticipantsChanged);
|
||||||
|
|
||||||
final callsCopylist = List.from(calls);
|
final callsCopylist = List.from(callSessions);
|
||||||
|
|
||||||
for (final call in callsCopylist) {
|
for (final call in callsCopylist) {
|
||||||
await call.updateMuteStatus();
|
await call.updateMuteStatus();
|
||||||
|
|
@ -1305,7 +1305,7 @@ class GroupCall {
|
||||||
|
|
||||||
onGroupCallEvent.add(GroupCallEvent.ParticipantsChanged);
|
onGroupCallEvent.add(GroupCallEvent.ParticipantsChanged);
|
||||||
|
|
||||||
final callsCopylist = List.from(calls);
|
final callsCopylist = List.from(callSessions);
|
||||||
|
|
||||||
for (final call in callsCopylist) {
|
for (final call in callsCopylist) {
|
||||||
await call.updateMuteStatus();
|
await call.updateMuteStatus();
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,11 @@ class VoIP {
|
||||||
final String partyId = content['party_id'];
|
final String partyId = content['party_id'];
|
||||||
final int lifetime = content['lifetime'];
|
final int lifetime = content['lifetime'];
|
||||||
final String? confId = content['conf_id'];
|
final String? confId = content['conf_id'];
|
||||||
|
|
||||||
|
// msc3401 group call invites send deviceId and senderSessionId in to device messages
|
||||||
final String? deviceId = content['device_id'];
|
final String? deviceId = content['device_id'];
|
||||||
|
final String? senderSessionId = content['sender_session_id'];
|
||||||
|
|
||||||
final call = calls[callId];
|
final call = calls[callId];
|
||||||
|
|
||||||
Logs().d(
|
Logs().d(
|
||||||
|
|
@ -232,7 +236,7 @@ class VoIP {
|
||||||
newCall.remotePartyId = partyId;
|
newCall.remotePartyId = partyId;
|
||||||
newCall.remoteUser = await room.requestUser(senderId);
|
newCall.remoteUser = await room.requestUser(senderId);
|
||||||
newCall.opponentDeviceId = deviceId;
|
newCall.opponentDeviceId = deviceId;
|
||||||
newCall.opponentSessionId = content['sender_session_id'];
|
newCall.opponentSessionId = senderSessionId;
|
||||||
if (!delegate.canHandleNewCall &&
|
if (!delegate.canHandleNewCall &&
|
||||||
(confId == null || confId != currentGroupCID)) {
|
(confId == null || confId != currentGroupCID)) {
|
||||||
Logs().v(
|
Logs().v(
|
||||||
|
|
@ -263,16 +267,22 @@ class VoIP {
|
||||||
// initWithInvite, we might set it to callId even after it was reset to null
|
// initWithInvite, we might set it to callId even after it was reset to null
|
||||||
// by terminate.
|
// by terminate.
|
||||||
currentCID = callId;
|
currentCID = callId;
|
||||||
|
try {
|
||||||
await newCall.initWithInvite(
|
await newCall.initWithInvite(
|
||||||
callType, offer, sdpStreamMetadata, lifetime, confId != null);
|
callType, offer, sdpStreamMetadata, lifetime, confId != null);
|
||||||
|
} catch (e, s) {
|
||||||
|
Logs().e('[VOIP] initWithInvite failed', e, s);
|
||||||
|
}
|
||||||
|
|
||||||
// Popup CallingPage for incoming call.
|
// Popup CallingPage for incoming call.
|
||||||
if (confId == null && !newCall.callHasEnded) {
|
if (confId == null && !newCall.callHasEnded) {
|
||||||
await delegate.handleNewCall(newCall);
|
await delegate.handleNewCall(newCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
onIncomingCall.add(newCall);
|
if (confId != null) {
|
||||||
|
// the stream is used to monitor incoming peer calls in a mesh call
|
||||||
|
onIncomingCall.add(newCall);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> onCallAnswer(
|
Future<void> onCallAnswer(
|
||||||
|
|
@ -494,6 +504,19 @@ class VoIP {
|
||||||
'Ignoring call negotiation for room $roomId claiming to be for call in room ${call.room.id}');
|
'Ignoring call negotiation for room $roomId claiming to be for call in room ${call.room.id}');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (content['party_id'] != call.remotePartyId) {
|
||||||
|
Logs().w('Ignoring call negotiation, wrong partyId detected');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (content['party_id'] == call.localPartyId) {
|
||||||
|
Logs().w('Ignoring call negotiation echo');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ideally you also check the lifetime here and discard negotiation events
|
||||||
|
// if age of the event was older than the lifetime but as to device events
|
||||||
|
// do not have a unsigned age nor a origin_server_ts there's no easy way to
|
||||||
|
// override this one function atm
|
||||||
|
|
||||||
final description = content['description'];
|
final description = content['description'];
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue