onNegotiateReceived method

Future<void> onNegotiateReceived(
  1. SDPStreamMetadata? metadata,
  2. RTCSessionDescription description
)

Implementation

Future<void> onNegotiateReceived(
    SDPStreamMetadata? metadata, RTCSessionDescription description) async {
  final polite = direction == CallDirection.kIncoming;

  // Here we follow the perfect negotiation logic from
  // https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Perfect_negotiation
  final offerCollision = ((description.type == 'offer') &&
      (_makingOffer ||
          pc!.signalingState != RTCSignalingState.RTCSignalingStateStable));

  _ignoreOffer = !polite && offerCollision;
  if (_ignoreOffer) {
    Logs().i('Ignoring colliding negotiate event because we\'re impolite');
    return;
  }

  final prevLocalOnHold = await isLocalOnHold();

  if (metadata != null) {
    _updateRemoteSDPStreamMetadata(metadata);
  }

  try {
    await pc!.setRemoteDescription(description);
    RTCSessionDescription? answer;
    if (description.type == 'offer') {
      try {
        answer = await pc!.createAnswer({});
      } catch (e) {
        await terminate(CallParty.kLocal, CallErrorCode.createAnswer, true);
        rethrow;
      }

      await sendCallNegotiate(
          room,
          callId,
          CallTimeouts.defaultCallEventLifetime.inMilliseconds,
          localPartyId,
          answer.sdp!,
          type: answer.type!);
      await pc!.setLocalDescription(answer);
    }
  } catch (e, s) {
    Logs().e('[VOIP] onNegotiateReceived => ', e, s);
    await _getLocalOfferFailed(e);
    return;
  }

  final newLocalOnHold = await isLocalOnHold();
  if (prevLocalOnHold != newLocalOnHold) {
    _localHold = newLocalOnHold;
    fireCallEvent(CallStateChange.kLocalHoldUnhold);
  }
}