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);
        return;
      }

      await sendCallNegotiate(
          room, callId, Timeouts.lifetimeMs, 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(CallEvent.kLocalHoldUnhold);
  }
}