receiveRequest method

void receiveRequest(
  1. IncomingRequest request
)

Request reception

Implementation

void receiveRequest(IncomingRequest request) {
  DartSIP_C.SipMethod? method = request.method;

  // Check that request URI points to us.
  if (request.ruri!.user != _configuration!.uri.user &&
      request.ruri!.user != _contact!.uri!.user) {
    logger.debug('Request-URI does not point to us');
    if (request.method != SipMethod.ACK) {
      request.reply_sl(404);
    }

    return;
  }

  // Check request URI scheme.
  if (request.ruri!.scheme == DartSIP_C.SIPS) {
    request.reply_sl(416);

    return;
  }

  // Check transaction.
  if (checkTransaction(_transactions, request)) {
    return;
  }

  // Create the server transaction.
  if (method == SipMethod.INVITE) {
    /* eslint-disable no-*/
    InviteServerTransaction(this, _transport, request);
    /* eslint-enable no-*/
  } else if (method != SipMethod.ACK && method != SipMethod.CANCEL) {
    /* eslint-disable no-*/
    NonInviteServerTransaction(this, _transport, request);
    /* eslint-enable no-*/
  }

  /* RFC3261 12.2.2
   * Requests that do not change in any way the state of a dialog may be
   * received within a dialog (for example, an OPTIONS request).
   * They are processed as if they had been received outside the dialog.
   */
  if (method == SipMethod.OPTIONS) {
    request.reply(200);
  } else if (method == SipMethod.MESSAGE) {
    if (!hasListeners(EventNewMessage())) {
      request.reply(405);
      return;
    }
    Message message = Message(this);
    message.init_incoming(request);
    return;
  } else if (method == SipMethod.INVITE) {
    // Initial INVITE.
    if (request.to_tag != null && !hasListeners(EventNewRTCSession())) {
      request.reply(405);

      return;
    }
  }

  Dialog? dialog;
  RTCSession? session;

  // Initial Request.
  if (request.to_tag == null) {
    switch (method) {
      case SipMethod.INVITE:
        if (hasRTCPeerConnection) {
          if (request.hasHeader('replaces')) {
            ParsedData replaces = request.replaces;

            dialog = _findDialog(
                replaces.call_id, replaces.from_tag!, replaces.to_tag!);
            if (dialog != null) {
              session = dialog.owner;
              if (!session!.isEnded()) {
                session.receiveRequest(request);
              } else {
                request.reply(603);
              }
            } else {
              request.reply(481);
            }
          } else {
            session = RTCSession(this);
            session.init_incoming(request);
          }
        } else {
          logger.error('INVITE received but WebRTC is not supported');
          request.reply(488);
        }
        break;
      case SipMethod.BYE:
        // Out of dialog BYE received.
        request.reply(481);
        break;
      case SipMethod.CANCEL:
        session =
            _findSession(request.call_id!, request.from_tag, request.to_tag);
        if (session != null) {
          session.receiveRequest(request);
        } else {
          logger.debug('received CANCEL request for a non existent session');
        }
        break;
      case SipMethod.ACK:
        /* Absorb it.
         * ACK request without a corresponding Invite Transaction
         * and without To tag.
         */
        break;
      case SipMethod.NOTIFY:
        // Receive sip event.
        emit(EventSipEvent(request: request));
        request.reply(200);
        break;
      default:
        request.reply(405);
        break;
    }
  }
  // In-dialog request.
  else {
    dialog =
        _findDialog(request.call_id!, request.from_tag!, request.to_tag!);

    if (dialog != null) {
      dialog.receiveRequest(request);
    } else if (method == SipMethod.NOTIFY) {
      session =
          _findSession(request.call_id!, request.from_tag, request.to_tag);
      if (session != null) {
        session.receiveRequest(request);
      } else {
        logger
            .debug('received NOTIFY request for a non existent subscription');
        request.reply(481, 'Subscription does not exist');
      }
    }

    /* RFC3261 12.2.2
     * Request with to tag, but no matching dialog found.
     * Exception: ACK for an Invite request for which a dialog has not
     * been created.
     */
    else if (method != SipMethod.ACK) {
      request.reply(481);
    }
  }
}