Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Conditions Of Use
    *
    * This software was developed by employees of the National Institute of
    * Standards and Technology (NIST), an agency of the Federal Government.
    * Pursuant to title 15 Untied States Code Section 105, works of NIST
    * employees are not subject to copyright protection in the United States
    * and are considered to be in the public domain.  As a result, a formal
    * license is not needed to use the software.
   *
   * This software is provided by NIST as a service and is expressly
   * provided "AS IS."  NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
   * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
   * AND DATA ACCURACY.  NIST does not warrant or make any representations
   * regarding the use of the software or the results thereof, including but
   * not limited to the correctness, accuracy, reliability or usefulness of
   * the software.
   *
   * Permission to use this software is contingent upon your acceptance
   * of the terms of this agreement
   *
   * .
   *
   */
Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * /
  
  package gov.nist.javax.sip;
  
  
  
  import javax.sip.Dialog;
  import javax.sip.Timeout;
  
  /*
   * Contributions (bug fixes) made by: Daniel J. Martinez Manzano, Hagai Sela.
   * Bug reports by Shanti Kadiyala, Rhys Ulerich,Victor Hugo
   */
Implementation of the JAIN-SIP provider interface.

Author(s):
M. Ranganathan
Version:
1.2 $Revision: 1.83.2.1 $ $Date: 2010/11/23 19:23:10 $
  
  
  
      private SipListener sipListener;
  
     protected SipStackImpl sipStack;
 
     /*
      * A set of listening points associated with the provider At most one LP per
      * transport
      */
 
     private EventScanner eventScanner;
 
     private String address;
 
     private int port;
 
     private boolean automaticDialogSupportEnabled ; 
    
A string containing the 0.0.0.0 IPv4 ANY address.
 
     private String IN_ADDR_ANY = "0.0.0.0";

    
A string containing the ::0 IPv6 ANY address.
 
     private String IN6_ADDR_ANY = "::0";
 
     private boolean dialogErrorsAutomaticallyHandled = true;
     
     private SipProviderImpl() {
     	
     }

    
Stop processing messages for this provider. Post an empty message to our message processing queue that signals us to quit.
 
     protected void stop() {
         // Put an empty event in the queue and post ourselves a message.
         if (.isLoggingEnabled())
             .getStackLogger().logDebug("Exiting provider");
         for (Iterator it = .values().iterator(); it.hasNext();) {
             ListeningPointImpl listeningPoint = (ListeningPointImplit.next();
             listeningPoint.removeSipProvider();
         }
         this..stop();
 
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#getListeningPoint(java.lang.String)
      */
     public ListeningPoint getListeningPoint(String transport) {
         if (transport == null)
             throw new NullPointerException("Null transport param");
         return (ListeningPointthis..get(transport
                 .toUpperCase());
     }

    
Handle the SIP event - because we have only one listener and we are already in the context of a separate thread, we dont need to enque the event and signal another thread.

Parameters:
sipEvent is the event to process.
 
 
     public void handleEvent(EventObject sipEventSIPTransaction transaction) {
             .getStackLogger().logDebug(
                     "handleEvent " + sipEvent + "currentTransaction = "
                             + transaction + "this.sipListener = "
                             + this.getSipListener() + "sipEvent.source = "
                             + sipEvent.getSource());
             if (sipEvent instanceof RequestEvent) {
                 Dialog dialog = ((RequestEventsipEvent).getDialog();
                 if ( .isLoggingEnabled(.))  .getStackLogger().logDebug("Dialog = " + dialog);
             } else if (sipEvent instanceof ResponseEvent) {
                 Dialog dialog = ((ResponseEventsipEvent).getDialog();
                 if (.isLoggingEnabled(.) ) .getStackLogger().logDebug("Dialog = " + dialog);
             }
             .getStackLogger().logStackTrace();
         }
 
         EventWrapper eventWrapper = new EventWrapper(sipEventtransaction);
 
         if (!.) {
             // Run the event in the context of a single thread.
             this..addEvent(eventWrapper);
         } else {
             // just call the delivery method
             this..deliverEvent(eventWrapper);
         }
     }

    
Creates a new instance of SipProviderImpl
 
     protected SipProviderImpl(SipStackImpl sipStack) {
         this. = sipStack.getEventScanner(); // for quick access.
         this. = sipStack;
         this..incrementRefcount();
         this. = this.
                 .isAutomaticDialogSupportEnabled();
     }
 
     /*
      * (non-Javadoc)
      *
      * @see java.lang.Object#clone()
      */
     protected Object clone() throws java.lang.CloneNotSupportedException {
         throw new java.lang.CloneNotSupportedException();
     }
 
     
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#addSipListener(javax.sip.SipListener)
      */
     public void addSipListener(SipListener sipListener)
             throws TooManyListenersException {
 
         if (. == null) {
             . = sipListener;
         } else if (. != sipListener) {
             throw new TooManyListenersException(
                     "Stack already has a listener. Only one listener per stack allowed");
         }
 
             .getStackLogger().logDebug("add SipListener " + sipListener);
         this. = sipListener;
 
     }
 
     /*
      * This method is deprecated (non-Javadoc)
      *
      * @see javax.sip.SipProvider#getListeningPoint()
      */
 
     public ListeningPoint getListeningPoint() {
         if (this..size() > 0)
             return (ListeningPointthis..values().iterator()
                     .next();
         else
             return null;
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#getNewCallId()
      */
     public CallIdHeader getNewCallId() {
         String callId = Utils.getInstance().generateCallIdentifier(this.getListeningPoint()
                 .getIPAddress());
         CallID callid = new CallID();
         try {
             callid.setCallId(callId);
         } catch (java.text.ParseException ex) {
         }
         return callid;
 
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#getNewClientTransaction(javax.sip.message.Request)
      */
             throws TransactionUnavailableException {
         if (request == null)
             throw new NullPointerException("null request");
         if (!.isAlive())
             throw new TransactionUnavailableException("Stack is stopped");
 
         SIPRequest sipRequest = (SIPRequestrequest;
         if (sipRequest.getTransaction() != null)
             throw new TransactionUnavailableException(
                     "Transaction already assigned to request");
         if ( sipRequest.getMethod().equals(.)) {
             throw new TransactionUnavailableException ("Cannot create client transaction for  " + .);
         }
         // Be kind and assign a via header for this provider if the user is
         // sloppy
         if (sipRequest.getTopmostVia() == null) {
             ListeningPointImpl lp = (ListeningPointImplthis
                     .getListeningPoint("udp");
             Via via = lp.getViaHeader();
             request.setHeader(via);
         }
         // Give the request a quick check to see if all headers are assigned.
         try {
             sipRequest.checkHeaders();
         } catch (ParseException ex) {
             throw new TransactionUnavailableException(ex.getMessage(), ex);
         }
 
         /*
          * User decided to give us his own via header branch. Lets see if it
          * results in a clash. If so reject the request.
          */
         if (sipRequest.getTopmostVia().getBranch() != null
                 && sipRequest.getTopmostVia().getBranch().startsWith(
                         .)
                 && .findTransaction((SIPRequestrequestfalse) != null) {
             throw new TransactionUnavailableException(
                     "Transaction already exists!");
         }
 
 
 
 
         if (request.getMethod().equalsIgnoreCase(.)) {
             SIPClientTransaction ct = (SIPClientTransaction
                     .findCancelTransaction((SIPRequestrequestfalse);
             if (ct != null) {
                 ClientTransaction retval = .createClientTransaction(
                         (SIPRequestrequestct.getMessageChannel());
 
                 ((SIPTransactionretval).addEventListener(this);
                 .addTransaction((SIPClientTransactionretval);
                 if (ct.getDialog() != null) {
                     ((SIPClientTransactionretval).setDialog((SIPDialogct
                             .getDialog(), sipRequest.getDialogId(false));
 
                 }
                 return retval;
             }
 
         }
             .getStackLogger().logDebug(
                     "could not find existing transaction for "
                             + ((SIPRequestrequest).getFirstLine()
                             + " creating a new one ");
 
         // Could not find a dialog or the route is not set in dialog.
 
         Hop hop = null;
         try {
             hop = .getNextHop((SIPRequestrequest);
             if (hop == null)
                 throw new TransactionUnavailableException(
                         "Cannot resolve next hop -- transaction unavailable");
         } catch (SipException ex) {
             throw new TransactionUnavailableException(
                     "Cannot resolve next hop -- transaction unavailable"ex);
         }
         String transport = hop.getTransport();
         ListeningPointImpl listeningPoint = (ListeningPointImplthis
                 .getListeningPoint(transport);
 
         String dialogId = sipRequest.getDialogId(false);
         SIPDialog dialog = .getDialog(dialogId);
         if (dialog != null && dialog.getState() == .) {
 
             // throw new TransactionUnavailableException
             // ("Found a terminated dialog -- possible re-use of old tag
             // parameters");
             .removeDialog(dialog);
 
         }
 
         // An out of dialog route was found. Assign this to the
         // client transaction.
 
         try {
             // Set the brannch id before you ask for a tx.
             // If the user has set his own branch Id and the
             // branch id starts with a valid prefix, then take it.
             // otherwise, generate one. If branch ID checking has 
             // been requested, set the branch ID.
             String branchId = null;
             if (sipRequest.getTopmostVia().getBranch() == null
                     || !sipRequest.getTopmostVia().getBranch().startsWith(
                             .)
                             || .checkBranchId() ) {
                 branchId = Utils.getInstance().generateBranchId();
 
                 sipRequest.getTopmostVia().setBranch(branchId);
             }
             Via topmostVia = sipRequest.getTopmostVia();
 
             //set port and transport if user hasn't already done this.
             if(topmostVia.getTransport() == null)
                 topmostVia.setTransport(transport);
 
             if(topmostVia.getPort() == -1)
                 topmostVia.setPort(listeningPoint.getPort());
             branchId = sipRequest.getTopmostVia().getBranch();
 
             SIPClientTransaction ct = (SIPClientTransaction
                     .createMessageChannel(sipRequestlisteningPoint
                             .getMessageProcessor(), hop);
             if (ct == null)
                 throw new TransactionUnavailableException("Cound not create tx");
             ct.setNextHop(hop);
             ct.setOriginalRequest(sipRequest);
             ct.setBranch(branchId);
             // if the stack supports dialogs then
             if (.isDialogCreated(request.getMethod())) {
                 // create a new dialog to contain this transaction
                 // provided this is necessary.
                 // This could be a re-invite
                 // in which case the dialog is re-used.
                 // (but noticed by Brad Templeton)
                 if (dialog != null)
                     ct.setDialog(dialogsipRequest.getDialogId(false));
                 else if (this.isAutomaticDialogSupportEnabled()) {
                     SIPDialog sipDialog = .createDialog(ct);
                     ct.setDialog(sipDialogsipRequest.getDialogId(false));
                 }
             } else {
                 if (dialog != null) {
                     ct.setDialog(dialogsipRequest.getDialogId(false));
                 }
 
             }
 
             // The provider is the event listener for all transactions.
             ct.addEventListener(this);
             return (ClientTransactionct;
         } catch (IOException ex) {
 
             throw new TransactionUnavailableException(
                     "Could not resolve next hop or listening point unavailable! ",
                     ex);
 
         } catch (java.text.ParseException ex) {
             InternalErrorHandler.handleException(ex);
             throw new TransactionUnavailableException(
                     "Unexpected Exception FIXME! "ex);
         } catch (InvalidArgumentException ex) {
             InternalErrorHandler.handleException(ex);
             throw new TransactionUnavailableException(
                     "Unexpected Exception FIXME! "ex);
         }
 
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#getNewServerTransaction(javax.sip.message.Request)
      */
             throws TransactionAlreadyExistsException,
             TransactionUnavailableException {
 
         if (!.isAlive())
             throw new TransactionUnavailableException("Stack is stopped");
         SIPServerTransaction transaction = null;
         SIPRequest sipRequest = (SIPRequestrequest;
         try {
             sipRequest.checkHeaders();
         } catch (ParseException ex) {
             throw new TransactionUnavailableException(ex.getMessage(), ex);
         }
 
         if ( request.getMethod().equals(.)) {
             if ( .isLoggingEnabled())
                 .getStackLogger().logError("Creating server transaction for ACK -- makes no sense!");
             throw new TransactionUnavailableException("Cannot create Server transaction for ACK ");
         }
         /*
          * Got a notify.
          */
         if (sipRequest.getMethod().equals(.)
                 && sipRequest.getFromTag() != null
                 && sipRequest.getToTag() == null) {
 
             SIPClientTransaction ct = .findSubscribeTransaction(
                     sipRequest, (ListeningPointImplthis.getListeningPoint());
             /* Issue 104 */
             if (ct == null && ! .isDeliverUnsolicitedNotify()) {
                 throw new TransactionUnavailableException(
                         "Cannot find matching Subscription (and gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY not set)");
             }
         }
         if ( !.acquireSem()) {
             throw new TransactionUnavailableException(
             "Transaction not available -- could not acquire stack lock");
         }
         try {
             if (.isDialogCreated(sipRequest.getMethod())) {
                 if (.findTransaction((SIPRequestrequesttrue) != null)
                     throw new TransactionAlreadyExistsException(
                     "server transaction already exists!");
 
                 transaction = (SIPServerTransaction) ((SIPRequestrequest)
                 .getTransaction();
                 if (transaction == null)
                     throw new TransactionUnavailableException(
                     "Transaction not available");
                 if (transaction.getOriginalRequest() == null)
                     transaction.setOriginalRequest(sipRequest);
                 try {
                     .addTransaction(transaction);
                 } catch (IOException ex) {
                     throw new TransactionUnavailableException(
                     "Error sending provisional response");
                 }
                 // So I can handle timeouts.
                 transaction.addEventListener(this);
                 if (isAutomaticDialogSupportEnabled()) {
                     // If automatic dialog support is enabled then
                     // this tx gets his own dialog.
                     String dialogId = sipRequest.getDialogId(true);
                     SIPDialog dialog = .getDialog(dialogId);
                     if (dialog == null) {
                         dialog = .createDialog(transaction);
 
                     }
                     transaction.setDialog(dialogsipRequest.getDialogId(true));
                     if (sipRequest.getMethod().equals(.) && this.isDialogErrorsAutomaticallyHandled()) {
                         .putInMergeTable(transactionsipRequest);
                     }
                     dialog.addRoute(sipRequest);
                     if (dialog.getRemoteTag() != null
                             && dialog.getLocalTag() != null) {
                         this..putDialog(dialog);
                     }
                 }
 
             } else {
                 if (isAutomaticDialogSupportEnabled()) {
                     /*
                      * Under automatic dialog support, dialog is tied into a transaction. You cannot
                      * create a server tx except for dialog creating transactions. After that, all
                      * subsequent transactions are created for you by the stack.
                      */
                     transaction = (SIPServerTransaction.findTransaction(
                             (SIPRequestrequesttrue);
                     if (transaction != null)
                         throw new TransactionAlreadyExistsException(
                         "Transaction exists! ");
                     transaction = (SIPServerTransaction) ((SIPRequestrequest)
                     .getTransaction();
                     if (transaction == null)
                         throw new TransactionUnavailableException(
                         "Transaction not available!");
                     if (transaction.getOriginalRequest() == null)
                         transaction.setOriginalRequest(sipRequest);
                     // Map the transaction.
                     try {
                         .addTransaction(transaction);
                     } catch (IOException ex) {
                         throw new TransactionUnavailableException(
                         "Could not send back provisional response!");
                     }
 
                     // If there is a dialog already assigned then just update the
                     // dialog state.
                     String dialogId = sipRequest.getDialogId(true);
                     SIPDialog dialog = .getDialog(dialogId);
                     if (dialog != null) {
                         dialog.addTransaction(transaction);
                         dialog.addRoute(sipRequest);
                         transaction.setDialog(dialogsipRequest.getDialogId(true));
                     }
 
                 } else {
                     transaction = (SIPServerTransaction.findTransaction(
                             (SIPRequestrequesttrue);
                     if (transaction != null)
                         throw new TransactionAlreadyExistsException(
                         "Transaction exists! ");
                     transaction = (SIPServerTransaction) ((SIPRequestrequest)
                     .getTransaction();
                     if (transaction != null) {
                         if (transaction.getOriginalRequest() == null)
                             transaction.setOriginalRequest(sipRequest);
                         // Map the transaction.
                         .mapTransaction(transaction);
 
                         // If there is a dialog already assigned then just
                         // assign the dialog to the transaction.
                         String dialogId = sipRequest.getDialogId(true);
                         SIPDialog dialog = .getDialog(dialogId);
                         if (dialog != null) {
                             dialog.addTransaction(transaction);
                             dialog.addRoute(sipRequest);
                             transaction.setDialog(dialogsipRequest
                                     .getDialogId(true));
                         }
 
                         return transaction;
                     } else {
                         // tx does not exist so create the tx.
 
                         MessageChannel mc = (MessageChannelsipRequest
                         .getMessageChannel();
                         transaction = .createServerTransaction(mc);
                         if (transaction == null)
                             throw new TransactionUnavailableException(
                             "Transaction unavailable -- too many servrer transactions");
 
                         transaction.setOriginalRequest(sipRequest);
                         .mapTransaction(transaction);
 
                         // If there is a dialog already assigned then just
                         // assign the dialog to the transaction.
                         String dialogId = sipRequest.getDialogId(true);
                         SIPDialog dialog = .getDialog(dialogId);
                         if (dialog != null) {
                             dialog.addTransaction(transaction);
                             dialog.addRoute(sipRequest);
                             transaction.setDialog(dialogsipRequest
                                     .getDialogId(true));
                         }
 
                         return transaction;
                     }
                 }
 
             }
             return transaction;
         } finally {
             .releaseSem();
         }
 
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#getSipStack()
      */
     public SipStack getSipStack() {
         return (SipStackthis.;
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#removeSipListener(javax.sip.SipListener)
      */
     public void removeSipListener(SipListener sipListener) {
         if (sipListener == this.getSipListener()) {
             this. = null;
         }
 
         boolean found = false;
 
         for (Iterator<SipProviderImplit = .getSipProviders(); it.hasNext();) {
             SipProviderImpl nextProvider = (SipProviderImplit.next();
             if (nextProvider.getSipListener() != null)
                 found = true;
         }
         if (!found) {
             . = null;
         }
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#sendRequest(javax.sip.message.Request)
      */
     public void sendRequest(Request requestthrows SipException {
         if (!.isAlive())
             throw new SipException("Stack is stopped.");
 
         // mranga: added check to ensure we are not sending empty (keepalive)
         // message.
         if (((SIPRequestrequest).getRequestLine() != null
                 && request.getMethod().equals(.)) {
             Dialog dialog = .getDialog(((SIPRequestrequest)
                     .getDialogId(false));
             if (dialog != null && dialog.getState() != null) {
             	if (.isLoggingEnabled())
             		.getStackLogger().logWarning(
                         "Dialog exists -- you may want to use Dialog.sendAck() "
                                 + dialog.getState());
             }
         }
         Hop hop = .getRouter((SIPRequestrequest).getNextHop(request);
         if (hop == null)
             throw new SipException("could not determine next hop!");
         SIPRequest sipRequest = (SIPRequestrequest;
         // Check if we have a valid via.
         // Null request is used to send default proxy keepalive messages.
         if ((!sipRequest.isNullRequest()) && sipRequest.getTopmostVia() == null)
             throw new SipException("Invalid SipRequest -- no via header!");
 
         try {
             /*
              * JvB: Via branch should already be OK, dont touch it here? Some
              * apps forward statelessly, and then it's not set. So set only when
              * not set already, dont overwrite CANCEL branch here..
              */
             if (!sipRequest.isNullRequest()) {
                 Via via = sipRequest.getTopmostVia();
                 String branch = via.getBranch();
                 if (branch == null || branch.length() == 0) {
                     via.setBranch(sipRequest.getTransactionId());
                 }
             }
             MessageChannel messageChannel = null;
             if (this..containsKey(hop.getTransport()
                     .toUpperCase()))
                 messageChannel = .createRawMessageChannel(
                         this.getListeningPoint(hop.getTransport()).getIPAddress(),
                         this.getListeningPoint(hop.getTransport()).getPort(), hop);
             if (messageChannel != null) {
                 messageChannel.sendMessage((SIPMessagesipRequest,hop);
             } else {
                 throw new SipException(
                         "Could not create a message channel for "
                                 + hop.toString());
             }
         } catch (IOException ex) {
             if (.isLoggingEnabled()) {
                 .getStackLogger().logException(ex);
             }
 
             throw new SipException(
                     "IO Exception occured while Sending Request"ex);
 
         } catch (ParseException ex1) {
             InternalErrorHandler.handleException(ex1);
         } finally {
             if (.isLoggingEnabled(.))
                 .getStackLogger().logDebug(
                         "done sending " + request.getMethod() + " to hop "
                                 + hop);
         }
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#sendResponse(javax.sip.message.Response)
      */
     public void sendResponse(Response responsethrows SipException {
         if (!.isAlive())
             throw new SipException("Stack is stopped");
         SIPResponse sipResponse = (SIPResponseresponse;
         Via via = sipResponse.getTopmostVia();
         if (via == null)
             throw new SipException("No via header in response!");
         SIPServerTransaction st = (SIPServerTransaction.findTransaction((SIPMessage)responsetrue);
         if ( st != null   && st.getState() != . && this.isAutomaticDialogSupportEnabled()) {
             throw new SipException("Transaction exists -- cannot send response statelessly");
         }
         String transport = via.getTransport();
 
         // check to see if Via has "received paramaeter". If so
         // set the host to the via parameter. Else set it to the
         // Via host.
         String host = via.getReceived();
 
         if (host == null)
             host = via.getHost();
 
         // Symmetric nat support
         int port = via.getRPort();
         if (port == -1) {
             port = via.getPort();
             if (port == -1) {
                 if (transport.equalsIgnoreCase("TLS"))
                     port = 5061;
                 else
                     port = 5060;
             }
         }
 
         // for correct management of IPv6 addresses.
         if (host.indexOf(":") > 0)
             if (host.indexOf("[") < 0)
                 host = "[" + host + "]";
 
         Hop hop = .getAddressResolver().resolveAddress(
                 new HopImpl(hostporttransport));
 
         try {
             ListeningPointImpl listeningPoint = (ListeningPointImplthis
                     .getListeningPoint(transport);
             if (listeningPoint == null)
                 throw new SipException(
                         "whoopsa daisy! no listening point found for transport "
                                 + transport);
             MessageChannel messageChannel = .createRawMessageChannel(
                     this.getListeningPoint(hop.getTransport()).getIPAddress(),
                     listeningPoint.porthop);
             messageChannel.sendMessage(sipResponse);
         } catch (IOException ex) {
             throw new SipException(ex.getMessage());
         }
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#setListeningPoint(javax.sip.ListeningPoint)
      */
     public synchronized void setListeningPoint(ListeningPoint listeningPoint) {
         if (listeningPoint == null)
             throw new NullPointerException("Null listening point");
         ListeningPointImpl lp = (ListeningPointImpllisteningPoint;
         lp.sipProvider = this;
         String transport = lp.getTransport().toUpperCase();
         this. = listeningPoint.getIPAddress();
         this. = listeningPoint.getPort();
         // This is the first listening point.
         this..clear();
         this..put(transportlisteningPoint);
 
     }
 
     /*
      * (non-Javadoc)
      *
      * @see javax.sip.SipProvider#getNewDialog(javax.sip.Transaction)
      */
 
     public Dialog getNewDialog(Transaction transactionthrows SipException {
         if (transaction == null)
             throw new NullPointerException("Null transaction!");
 
         if (!.isAlive())
             throw new SipException("Stack is stopped.");
 
         if (isAutomaticDialogSupportEnabled())
             throw new SipException(" Error - AUTOMATIC_DIALOG_SUPPORT is on");
 
         if (!.isDialogCreated(transaction.getRequest().getMethod()))
             throw new SipException("Dialog cannot be created for this method "
                     + transaction.getRequest().getMethod());
 
         SIPDialog dialog = null;
         SIPTransaction sipTransaction = (SIPTransactiontransaction;
 
         if (transaction instanceof ServerTransaction) {
             SIPServerTransaction st = (SIPServerTransactiontransaction;
             Response response = st.getLastResponse();
             if (response != null) {
                 if (response.getStatusCode() != 100)
                     throw new SipException(
                             "Cannot set dialog after response has been sent");
             }
             SIPRequest sipRequest = (SIPRequesttransaction.getRequest();
             String dialogId = sipRequest.getDialogId(true);
             dialog = .getDialog(dialogId);
             if (dialog == null) {
                 dialog = .createDialog((SIPTransactiontransaction);
                 // create and register the dialog and add the inital route set.
                 dialog.addTransaction(sipTransaction);
                 dialog.addRoute(sipRequest);
                 sipTransaction.setDialog(dialognull);
 
             } else {
                 sipTransaction.setDialog(dialogsipRequest.getDialogId(true));
             }
             if (sipRequest.getMethod().equals(.) && this.isDialogErrorsAutomaticallyHandled()) {
                 .putInMergeTable(stsipRequest);
             }
         } else {
 
             SIPClientTransaction sipClientTx = (SIPClientTransactiontransaction;
 
             SIPResponse response = sipClientTx.getLastResponse();
 
             if (response == null) {
                 // A response has not yet been received, then set this up as the
                 // default dialog.
                 SIPRequest request = (SIPRequestsipClientTx.getRequest();
 
                 String dialogId = request.getDialogId(false);
                 dialog = .getDialog(dialogId);
                 if (dialog != null) {
                     throw new SipException("Dialog already exists!");
                 } else {
                     dialog = .createDialog(sipTransaction);
                 }
                 sipClientTx.setDialog(dialognull);
 
             } else {
                 throw new SipException(
                         "Cannot call this method after response is received!");
             }
         }
         dialog.addEventListener(this);
         return dialog;
 
     }

    
Invoked when an error has ocurred with a transaction. Propagate up to the listeners.

Parameters:
transactionErrorEvent Error event.
 
     public void transactionErrorEvent(
             SIPTransactionErrorEvent transactionErrorEvent) {
         SIPTransaction transaction = (SIPTransactiontransactionErrorEvent
                 .getSource();
 
         if (transactionErrorEvent.getErrorID() == .) {
             // There must be a way to inform the TU here!!
             if (.isLoggingEnabled(.)) {
                 .getStackLogger().logDebug(
                         "TransportError occured on " + transaction);
             }
             // Treat this like a timeout event. (Suggestion from Christophe).
             Object errorObject = transactionErrorEvent.getSource();
             Timeout timeout = .;
             TimeoutEvent ev = null;
 
             if (errorObject instanceof SIPServerTransaction) {
                 ev = new TimeoutEvent(this, (ServerTransactionerrorObject,
                         timeout);
             } else {
                 SIPClientTransaction clientTx = (SIPClientTransactionerrorObject;
                 Hop hop = clientTx.getNextHop();
                 if ( .getRouter() instanceof RouterExt ) {
                     ((RouterExt.getRouter()).transactionTimeout(hop);
                 }
                 ev = new TimeoutEvent(this, (ClientTransactionerrorObject,
                         timeout);
             }
             // Handling transport error like timeout
             this.handleEvent(ev, (SIPTransactionerrorObject);
         } else if (transactionErrorEvent.getErrorID() == .) {
             // This is a timeout event.
             Object errorObject = transactionErrorEvent.getSource();
             Timeout timeout = .;
             TimeoutEvent ev = null;
 
             if (errorObject instanceof SIPServerTransaction) {
                 ev = new TimeoutEvent(this, (ServerTransactionerrorObject,
                         timeout);
             } else {
                 SIPClientTransaction clientTx = (SIPClientTransactionerrorObject;
                 Hop hop = clientTx.getNextHop();
                 if ( .getRouter() instanceof RouterExt ) {
                     ((RouterExt.getRouter()).transactionTimeout(hop);
                 }
 
                 ev = new TimeoutEvent(this, (ClientTransactionerrorObject,
                         timeout);
             }
             this.handleEvent(ev, (SIPTransactionerrorObject);
 
         } else if (transactionErrorEvent.getErrorID() == .) {
             // This is a timeout retransmit event.
             // We should never get this if retransmit filter is
             // enabled (ie. in that case the stack should handle.
             // all retransmits.
             Object errorObject = transactionErrorEvent.getSource();
             Transaction tx = (TransactionerrorObject;
 
             if (tx.getDialog() != null)
                 InternalErrorHandler.handleException("Unexpected event !",
                         this..getStackLogger());
 
             Timeout timeout = .;
             TimeoutEvent ev = null;
 
             if (errorObject instanceof SIPServerTransaction) {
                 ev = new TimeoutEvent(this, (ServerTransactionerrorObject,
                         timeout);
             } else {
                 ev = new TimeoutEvent(this, (ClientTransactionerrorObject,
                         timeout);
             }
             this.handleEvent(ev, (SIPTransactionerrorObject);
         }
     }
     
     /*
      * (non-Javadoc)
      * @see gov.nist.javax.sip.stack.SIPDialogEventListener#dialogErrorEvent(gov.nist.javax.sip.stack.SIPDialogErrorEvent)
      */
     public synchronized void dialogErrorEvent(SIPDialogErrorEvent dialogErrorEvent) {
         SIPDialog sipDialog = (SIPDialogdialogErrorEvent.getSource();
         Reason reason = .;
         if (dialogErrorEvent.getErrorID() == .) {
         	reason.;
         } else if (dialogErrorEvent.getErrorID() == .) {
             reason = .;
         }
             .getStackLogger().logDebug(
                     "Dialog TimeoutError occured on " + sipDialog);
         }
         DialogTimeoutEvent ev = new DialogTimeoutEvent(thissipDialogreason);
         // Handling transport error like timeout
         this.handleEvent(evnull);
     }
 
     /*
     * (non-Javadoc)
     *
     * @see javax.sip.SipProvider#getListeningPoints()
     */
    public synchronized ListeningPoint[] getListeningPoints() {
        ListeningPoint[] retval = new ListeningPointImpl[this.
                .size()];
        this..values().toArray(retval);
        return retval;
    }
    /*
     * (non-Javadoc)
     *
     * @see javax.sip.SipProvider#addListeningPoint(javax.sip.ListeningPoint)
     */
    public synchronized void addListeningPoint(ListeningPoint listeningPoint)
            throws ObjectInUseException {
        ListeningPointImpl lp = (ListeningPointImpllisteningPoint;
        if (lp.sipProvider != null && lp.sipProvider != this)
            throw new ObjectInUseException(
                    "Listening point assigned to another provider");
        String transport = lp.getTransport().toUpperCase();
        if (this..isEmpty()) {
            // first one -- record the IP address/port of the LP
            this. = listeningPoint.getIPAddress();
            this. = listeningPoint.getPort();
        } else {
            if ((!this..equals(listeningPoint.getIPAddress()))
                    || this. != listeningPoint.getPort())
                throw new ObjectInUseException(
                        "Provider already has different IP Address associated");
        }
        if (this..containsKey(transport)
                && this..get(transport) != listeningPoint)
            throw new ObjectInUseException(
                    "Listening point already assigned for transport!");
        // This is for backwards compatibility.
        lp.sipProvider = this;
        this..put(transportlp);