/**
   * This method initiates SIP_BYE for established DIALOG
   *
   * @param dialog - DIALOG to terminate
   */
  public void bye(final Dialog dialog) {
    assert TransactionUtils.isTransactionExecutionThread()
        : "Code run in wrong thread. Must be run in TransactionThread. Now in "
            + Thread.currentThread();
    assert !done.get();

    if (!done.get()) {
      assert STATED == dialog.getState()
          : "Wrong dialog state. Must be " + STATED + " now is " + dialog.getState();
      doBye(dialog, TRANSACTION_TIMEOUT);
    }
  }
  /**
   * Handles server noninvite message
   *
   * @param msg - noninvite message
   */
  public void handleIncomingBye(final Request msg) {

    assert TransactionUtils.isTransactionExecutionThread()
        : "Code run in wrong thread. Must be run in TransactionThread. Now in "
            + Thread.currentThread();
    assert !done.get();
    assert msg != null && MessageType.SIP_BYE == MessageType.parse(msg.getMethod());

    Logger.log("Remote party has sent noninvite");
    if (!done.get()) {

      final Dialog dialog = getStackContext().getDialogStorage().findDialogForMessage(msg);
      assert dialog != null;
      assert STATED == dialog.getState();

      dialog.getMessageHistory().addMessage(msg, true);

      final TransactionManager transactionManager = getTransactionManager();
      transactionManager.addListener(
          new FirstMessageResolver(SIP_BYE_SERVER.getName(), dialog, msg, transactionManager));

      final Transaction transaction =
          transactionManager.lookUpTransaction(dialog, null, SIP_BYE_SERVER);
      runAsynchronously(transaction, TRANSACTION_TIMEOUT);
    }
  }
示例#3
0
  /** Process the ACK request. Send the bye and complete the call flow. */
  public void processAck(RequestEvent requestEvent, ServerTransaction serverTransaction) {
    SipProvider sipProvider = (SipProvider) requestEvent.getSource();
    try {
      // System.out.println("*** shootme: got an ACK "
      // + requestEvent.getRequest());
      if (serverTransaction == null) {
        System.out.println("null server transaction -- ignoring the ACK!");
        return;
      }
      Dialog dialog = serverTransaction.getDialog();
      this.createdCount++;
      System.out.println(
          "Dialog Created = "
              + dialog.getDialogId()
              + " createdCount "
              + this.createdCount
              + " Dialog State = "
              + dialog.getState());

      if (this.dialogIds.contains(dialog.getDialogId())) {
        System.out.println("OOPS ! I already saw " + dialog.getDialogId());
      } else {
        this.dialogIds.add(dialog.getDialogId());
      }

      Request byeRequest = dialog.createRequest(Request.BYE);
      ClientTransaction tr = sipProvider.getNewClientTransaction(byeRequest);
      // System.out.println("shootme: got an ACK -- sending bye! ");
      dialog.sendRequest(tr);

    } catch (Exception ex) {
      ex.printStackTrace();
      System.exit(0);
    }
  }
  /**
   * Creates and sends a SUBSCRIBE request to the subscription <tt>Address</tt>/Request URI of a
   * specific <tt>Subscription</tt> in order to request receiving event notifications and adds the
   * specified <tt>Subscription</tt> to the list of subscriptions managed by this instance. The
   * added <tt>Subscription</tt> may later receive notifications to process the <tt>Request</tt>s
   * and/or <tt>Response</tt>s which constitute the signaling session associated with it. If the
   * attempt to create and send the SUBSCRIBE request fails, the specified <tt>Subscription</tt> is
   * not added to the list of subscriptions managed by this instance.
   *
   * @param subscription a <tt>Subscription</tt> which specifies the properties of the SUBSCRIBE
   *     request to be created and sent, to be added to the list of subscriptions managed by this
   *     instance
   * @throws OperationFailedException if we fail constructing or sending the subscription request.
   */
  public void subscribe(Subscription subscription) throws OperationFailedException {
    Dialog dialog = subscription.getDialog();

    if ((dialog != null) && DialogState.TERMINATED.equals(dialog.getState())) dialog = null;

    // create the subscription
    ClientTransaction subscribeTransaction = null;
    try {
      subscribeTransaction =
          (dialog == null)
              ? createSubscription(subscription, subscriptionDuration)
              : createSubscription(subscription, dialog, subscriptionDuration);
    } catch (OperationFailedException ex) {
      ProtocolProviderServiceSipImpl.throwOperationFailedException(
          "Failed to create the subscription", OperationFailedException.INTERNAL_ERROR, ex, logger);
    }

    // we register the contact to find him when the OK will arrive
    CallIdHeader callIdHeader =
        (CallIdHeader) subscribeTransaction.getRequest().getHeader(CallIdHeader.NAME);
    String callId = callIdHeader.getCallId();
    addSubscription(callId, subscription);

    // send the message
    try {
      if (dialog == null) subscribeTransaction.sendRequest();
      else dialog.sendRequest(subscribeTransaction);
    } catch (SipException ex) {
      // this contact will never been accepted or rejected
      removeSubscription(callId, subscription);

      ProtocolProviderServiceSipImpl.throwOperationFailedException(
          "Failed to send the subscription", OperationFailedException.NETWORK_FAILURE, ex, logger);
    }
  }
 private void checkReInvitePreconditions(final Dialog dialog, final Request msg)
     throws DialogStateException {
   if (EARLY == dialog.getState()) {
     throw new DialogStateException(
         dialog,
         REINVITE_FOR_EARLY_DIALOG,
         msg,
         "Can not update (reinvite) DIALOG. Dialog is not stated yet. Dialog  state is "
             + dialog.getState());
   }
   if (dialog.isReInviteInProgress()) {
     throw new DialogStateException(
         dialog,
         REINVITE_DURING_PREVIOUS_REINVITE,
         msg,
         "Can not update (reinvite) DIALOG. Previous reinvite still in progress.");
   }
 }
  private void checkUpdatePreconditions(final Dialog dialog, final Request msg)
      throws DialogStateException {
    if (STATED == dialog.getState()) {
      throw new DialogStateException(
          dialog,
          UPDATE_FOR_STATED_DIALOG,
          msg,
          "Can not update DIALOG. Dialog is stated already. ");
    }
    if (dialog.isUpdateInProgress()) {
      throw new DialogStateException(
          dialog,
          UPDATE_DURING_PREVIOUS_UPDATE,
          msg,
          "Can not update DIALOG. Previous update still in progress.");
    }

    /**
     * A UAS that receives an UPDATE before it has generated a final response to a previous UPDATE
     * on the same dialog MUST return a 500 response to the new UPDATE, and MUST include a
     * Retry-After HEADER field with a randomly chosen value between 0 and 10 seconds.
     *
     * <p>If an UPDATE is received that contains an offer, and the UAS has generated an offer (in an
     * UPDATE, PRACK or INVITE) to which it has not yet received an answer, the UAS MUST reject the
     * UPDATE with a 491 response. Similarly, if an UPDATE is received that contains an offer, and
     * the UAS has received an offer (in an UPDATE, PRACK, or INVITE) to which it has not yet
     * generated an answer, the UAS MUST reject the UPDATE with a 500 response, and MUST include a
     * Retry-After HEADER field with a randomly chosen value between 0 and 10 seconds.
     *
     * <p>If a UA receives an UPDATE for an existing dialog, it MUST check any version identifiers
     * in the SESSION description or, if there are no version identifiers, the content of the
     * SESSION description to see if it has changed. If the SESSION description has changed, the UAS
     * MUST adjust the SESSION parameters accordingly and generate an answer in the 2xx response.
     * However, unlike a re-INVITE, the UPDATE MUST be responded to promptly, and therefore the USER
     * cannot generally be prompted to approve the SESSION changes. If the UAS cannot change the
     * SESSION parameters without prompting the USER, it SHOULD reject the request with a 504
     * response. If the new SESSION description is not acceptable, the UAS can reject it by
     * returning a 488 (Not Acceptable Here) response for the UPDATE. This response SHOULD include a
     * Warning HEADER field.
     *
     * <p>If a UAC receives a 491 response to a UPDATE, it SHOULD start a timer with a value T
     * chosen as follows:
     *
     * <p>1. If the UAC is the owner of the Call-ID of the dialog ID (meaning it generated the
     * value), T has a randomly chosen value between 2.1 and 4 seconds in units of 10 ms.
     *
     * <p>2. If the UAC is not the owner of the Call-ID of the dialog ID, T has a randomly chosen
     * value between 0 and 2 seconds in units of 10 ms.
     *
     * <p>When the timer fires, the UAC SHOULD attempt the UPDATE once more, if it still desires for
     * that SESSION modification to take place. For example, if the call was already hung up with a
     * BYE, the UPDATE would not take place.
     */
  }
示例#7
0
  public void processBye(Request request, ServerTransaction serverTransactionId) {
    try {
      System.out.println("shootist:  got a bye .");
      if (serverTransactionId == null) {
        System.out.println("shootist:  null TID.");
        return;
      }
      Dialog dialog = serverTransactionId.getDialog();
      System.out.println("Dialog State = " + dialog.getState());
      Response response = messageFactory.createResponse(200, request);
      serverTransactionId.sendResponse(response);
      System.out.println("shootist:  Sending OK.");
      System.out.println("Dialog State = " + dialog.getState());

      this.shutDown();

    } catch (Exception ex) {
      ex.printStackTrace();
      System.exit(0);
    }
  }
示例#8
0
 /** Process the ACK request, forward it to the other leg. */
 public void processAck(RequestEvent requestEvent, ServerTransaction serverTransaction) {
   try {
     Dialog dialog = serverTransaction.getDialog();
     System.out.println("b2bua: got an ACK! ");
     System.out.println("Dialog State = " + dialog.getState());
     Dialog otherDialog = (Dialog) dialog.getApplicationData();
     Request request = otherDialog.createAck(otherDialog.getLocalSeqNumber());
     otherDialog.sendAck(request);
   } catch (Exception ex) {
     ex.printStackTrace();
   }
 }
示例#9
0
  public void processCancel(RequestEvent requestEvent, ServerTransaction serverTransactionId) {
    SipProvider sipProvider = (SipProvider) requestEvent.getSource();
    Request request = requestEvent.getRequest();
    try {
      System.out.println("shootme:  got a cancel.");
      if (serverTransactionId == null) {
        System.out.println("shootme:  null tid.");
        return;
      }
      Response response = messageFactory.createResponse(200, request);
      serverTransactionId.sendResponse(response);
      if (dialog.getState() != DialogState.CONFIRMED) {
        response = messageFactory.createResponse(Response.REQUEST_TERMINATED, inviteRequest);
        inviteTid.sendResponse(response);
      }

    } catch (Exception ex) {
      ex.printStackTrace();
      System.exit(0);
    }
  }
  /** This method tries to invite remote party */
  public void invite(final Dialog dialog) throws DialogStateException {
    Logger.log(TAG, "invite#started");
    assert TransactionUtils.isTransactionExecutionThread()
        : "Code run in wrong thread. Must be run in TransactionThread. Now in "
            + Thread.currentThread();
    assert !done.get();

    if (!done.get()) {
      if (STATED == dialog.getState()) {
        throw new DialogStateException(
            dialog,
            INVITE_FOR_STATED_DIALOG,
            null,
            "Can not invite remote party. Dialog is already stated.");
      }

      if (getStackContext().getConfig().useInviteRefresh()) {
        addDialogStateListener(dialog, listenerForInviteRefresh);
      }
      doInvite(dialog, LONG_TRANSACTION_TIMEOUT);
    }
    Logger.log(TAG, "invite#finished");
  }
示例#11
0
 /** Process the ACK request. Send the bye and complete the call flow. */
 public void processAck(RequestEvent requestEvent, ServerTransaction serverTransaction) {
   System.out.println("shootme: got an ACK! ");
   System.out.println("Dialog State = " + dialog.getState());
 }