/** * 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); } }
/** 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. */ }
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); } }
/** 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(); } }
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"); }
/** 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()); }