1600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/* 2600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Conditions Of Use 3600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 4600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * This software was developed by employees of the National Institute of 5600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Standards and Technology (NIST), an agency of the Federal Government. 6600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Pursuant to title 15 Untied States Code Section 105, works of NIST 7600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * employees are not subject to copyright protection in the United States 8600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * and are considered to be in the public domain. As a result, a formal 9600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * license is not needed to use the software. 10600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 11600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * This software is provided by NIST as a service and is expressly 12600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED 13600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF 14600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT 15600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * AND DATA ACCURACY. NIST does not warrant or make any representations 16600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * regarding the use of the software or the results thereof, including but 17600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * not limited to the correctness, accuracy, reliability or usefulness of 18600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * the software. 19600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 20600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Permission to use this software is contingent upon your acceptance 21600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * of the terms of this agreement 22600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 23600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * . 24600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 25600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 26600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/****************************************************************************** 27600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Product of NIST/ITL Advanced Networking Technologies Division (ANTD). * 28600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ******************************************************************************/ 29600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpackage gov.nist.javax.sip; 30600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 31600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.core.InternalErrorHandler; 32600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.DialogTimeoutEvent.Reason; 33600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.address.RouterExt; 34600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.header.CallID; 35600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.header.Via; 36600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.message.SIPMessage; 37600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.message.SIPRequest; 38600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.message.SIPResponse; 39600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.HopImpl; 40600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.MessageChannel; 41600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.SIPClientTransaction; 42600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.SIPDialog; 43600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.SIPDialogErrorEvent; 44600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.SIPDialogEventListener; 45600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.SIPServerTransaction; 46600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.SIPTransaction; 47600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.SIPTransactionErrorEvent; 48600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport gov.nist.javax.sip.stack.SIPTransactionEventListener; 49600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 50600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.io.IOException; 51600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.text.ParseException; 52600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.EventObject; 53600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.Iterator; 54600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.TooManyListenersException; 55600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport java.util.concurrent.ConcurrentHashMap; 56600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 57600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.ClientTransaction; 58600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.Dialog; 59600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.DialogState; 60600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.InvalidArgumentException; 61600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.ListeningPoint; 62600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.ObjectInUseException; 63600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.RequestEvent; 64600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.ResponseEvent; 65600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.ServerTransaction; 66600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.SipException; 67600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.SipListener; 68600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.SipStack; 69600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.Timeout; 70600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.TimeoutEvent; 71600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.Transaction; 72600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.TransactionAlreadyExistsException; 73600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.TransactionState; 74600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.TransactionUnavailableException; 75600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.address.Hop; 76600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.header.CallIdHeader; 77600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.message.Request; 78600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangimport javax.sip.message.Response; 79600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 80600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/* 81600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Contributions (bug fixes) made by: Daniel J. Martinez Manzano, Hagai Sela. 82600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Bug reports by Shanti Kadiyala, Rhys Ulerich,Victor Hugo 83600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 84600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang/** 85600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Implementation of the JAIN-SIP provider interface. 86600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 87600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @version 1.2 $Revision: 1.82 $ $Date: 2009/11/24 17:16:59 $ 88600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 89600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @author M. Ranganathan <br/> 90600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 91600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 92600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 93600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 94600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wangpublic class SipProviderImpl implements javax.sip.SipProvider, gov.nist.javax.sip.SipProviderExt, 95600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPTransactionEventListener, SIPDialogEventListener { 96600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 97600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private SipListener sipListener; 98600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 99600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected SipStackImpl sipStack; 100600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 101600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 102600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * A set of listening points associated with the provider At most one LP per 103600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * transport 104600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 105600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private ConcurrentHashMap listeningPoints; 106600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 107600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private EventScanner eventScanner; 108600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 109600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private String address; 110600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 111600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private int port; 112600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 113600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private boolean automaticDialogSupportEnabled ; 114600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 115600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * A string containing the 0.0.0.0 IPv4 ANY address. 116600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 117600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private String IN_ADDR_ANY = "0.0.0.0"; 118600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 119600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 120600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * A string containing the ::0 IPv6 ANY address. 121600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 122600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private String IN6_ADDR_ANY = "::0"; 123600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 124600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private boolean dialogErrorsAutomaticallyHandled = true; 125600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 126600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang private SipProviderImpl() { 127600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 128600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 129600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 130600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 131600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Stop processing messages for this provider. Post an empty message to our 132600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * message processing queue that signals us to quit. 133600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 134600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected void stop() { 135600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Put an empty event in the queue and post ourselves a message. 136600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) 137600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug("Exiting provider"); 138600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (Iterator it = listeningPoints.values().iterator(); it.hasNext();) { 139600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPointImpl listeningPoint = (ListeningPointImpl) it.next(); 140600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang listeningPoint.removeSipProvider(); 141600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 142600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.eventScanner.stop(); 143600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 144600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 145600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 146600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 147600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 148600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 149600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#getListeningPoint(java.lang.String) 150600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 151600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public ListeningPoint getListeningPoint(String transport) { 152600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transport == null) 153600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new NullPointerException("Null transport param"); 154600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return (ListeningPoint) this.listeningPoints.get(transport 155600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .toUpperCase()); 156600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 157600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 158600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 159600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Handle the SIP event - because we have only one listener and we are 160600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * already in the context of a separate thread, we dont need to enque the 161600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * event and signal another thread. 162600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 163600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @param sipEvent 164600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * is the event to process. 165600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 166600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 167600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 168600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void handleEvent(EventObject sipEvent, SIPTransaction transaction) { 169600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) { 170600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug( 171600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "handleEvent " + sipEvent + "currentTransaction = " 172600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + transaction + "this.sipListener = " 173600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + this.getSipListener() + "sipEvent.source = " 174600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + sipEvent.getSource()); 175600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipEvent instanceof RequestEvent) { 176600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Dialog dialog = ((RequestEvent) sipEvent).getDialog(); 177600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( sipStack.isLoggingEnabled()) sipStack.getStackLogger().logDebug("Dialog = " + dialog); 178600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (sipEvent instanceof ResponseEvent) { 179600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Dialog dialog = ((ResponseEvent) sipEvent).getDialog(); 180600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled() ) sipStack.getStackLogger().logDebug("Dialog = " + dialog); 181600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 182600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logStackTrace(); 183600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 184600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 185600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang EventWrapper eventWrapper = new EventWrapper(sipEvent, transaction); 186600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 187600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!sipStack.reEntrantListener) { 188600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Run the event in the context of a single thread. 189600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.eventScanner.addEvent(eventWrapper); 190600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 191600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // just call the delivery method 192600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.eventScanner.deliverEvent(eventWrapper); 193600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 194600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 195600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 196600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** Creates a new instance of SipProviderImpl */ 197600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected SipProviderImpl(SipStackImpl sipStack) { 198600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.eventScanner = sipStack.getEventScanner(); // for quick access. 199600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.sipStack = sipStack; 200600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.eventScanner.incrementRefcount(); 201600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.listeningPoints = new ConcurrentHashMap<String,ListeningPointImpl>(); 202600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.automaticDialogSupportEnabled = this.sipStack 203600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .isAutomaticDialogSupportEnabled(); 204600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.dialogErrorsAutomaticallyHandled = this.sipStack.isAutomaticDialogErrorHandlingEnabled(); 205600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 206600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 207600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 208600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 209600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 210600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see java.lang.Object#clone() 211600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 212600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang protected Object clone() throws java.lang.CloneNotSupportedException { 213600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new java.lang.CloneNotSupportedException(); 214600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 215600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 216600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 217600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 218600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 219600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 220600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#addSipListener(javax.sip.SipListener) 221600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 222600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void addSipListener(SipListener sipListener) 223600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throws TooManyListenersException { 224600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 225600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.sipListener == null) { 226600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.sipListener = sipListener; 227600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (sipStack.sipListener != sipListener) { 228600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TooManyListenersException( 229600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Stack already has a listener. Only one listener per stack allowed"); 230600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 231600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 232600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) 233600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug("add SipListener " + sipListener); 234600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.sipListener = sipListener; 235600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 236600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 237600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 238600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 239600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * This method is deprecated (non-Javadoc) 240600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 241600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#getListeningPoint() 242600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 243600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 244600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public ListeningPoint getListeningPoint() { 245600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (this.listeningPoints.size() > 0) 246600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return (ListeningPoint) this.listeningPoints.values().iterator() 247600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .next(); 248600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else 249600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return null; 250600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 251600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 252600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 253600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 254600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 255600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#getNewCallId() 256600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 257600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public CallIdHeader getNewCallId() { 258600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String callId = Utils.getInstance().generateCallIdentifier(this.getListeningPoint() 259600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getIPAddress()); 260600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang CallID callid = new CallID(); 261600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 262600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang callid.setCallId(callId); 263600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (java.text.ParseException ex) { 264600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 265600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return callid; 266600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 267600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 268600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 269600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 270600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 271600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 272600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#getNewClientTransaction(javax.sip.message.Request) 273600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 274600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public ClientTransaction getNewClientTransaction(Request request) 275600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throws TransactionUnavailableException { 276600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (request == null) 277600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new NullPointerException("null request"); 278600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!sipStack.isAlive()) 279600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException("Stack is stopped"); 280600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 281600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPRequest sipRequest = (SIPRequest) request; 282600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipRequest.getTransaction() != null) 283600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 284600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Transaction already assigned to request"); 285600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( sipRequest.getMethod().equals(Request.ACK)) { 286600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException ("Cannot create client transaction for " + Request.ACK); 287600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 288600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Be kind and assign a via header for this provider if the user is 289600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // sloppy 290600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipRequest.getTopmostVia() == null) { 291600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPointImpl lp = (ListeningPointImpl) this 292600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getListeningPoint("udp"); 293600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Via via = lp.getViaHeader(); 294600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang request.setHeader(via); 295600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 296600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Give the request a quick check to see if all headers are assigned. 297600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 298600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipRequest.checkHeaders(); 299600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (ParseException ex) { 300600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException(ex.getMessage(), ex); 301600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 302600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 303600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 304600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * User decided to give us his own via header branch. Lets see if it 305600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * results in a clash. If so reject the request. 306600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 307600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipRequest.getTopmostVia().getBranch() != null 308600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && sipRequest.getTopmostVia().getBranch().startsWith( 309600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPConstants.BRANCH_MAGIC_COOKIE) 310600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && sipStack.findTransaction((SIPRequest) request, false) != null) { 311600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 312600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Transaction already exists!"); 313600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 314600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 315600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 316600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 317600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 318600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (request.getMethod().equalsIgnoreCase(Request.CANCEL)) { 319600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPClientTransaction ct = (SIPClientTransaction) sipStack 320600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .findCancelTransaction((SIPRequest) request, false); 321600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (ct != null) { 322600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ClientTransaction retval = sipStack.createClientTransaction( 323600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang (SIPRequest) request, ct.getMessageChannel()); 324600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 325600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ((SIPTransaction) retval).addEventListener(this); 326600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.addTransaction((SIPClientTransaction) retval); 327600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (ct.getDialog() != null) { 328600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ((SIPClientTransaction) retval).setDialog((SIPDialog) ct 329600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getDialog(), sipRequest.getDialogId(false)); 330600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 331600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 332600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return retval; 333600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 334600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 335600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 336600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) 337600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug( 338600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "could not find existing transaction for " 339600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + ((SIPRequest) request).getFirstLine() 340600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + " creating a new one "); 341600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 342600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Could not find a dialog or the route is not set in dialog. 343600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 344600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Hop hop = null; 345600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 346600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang hop = sipStack.getNextHop((SIPRequest) request); 347600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (hop == null) 348600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 349600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Cannot resolve next hop -- transaction unavailable"); 350600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (SipException ex) { 351600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 352600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Cannot resolve next hop -- transaction unavailable", ex); 353600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 354600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String transport = hop.getTransport(); 355600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPointImpl listeningPoint = (ListeningPointImpl) this 356600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getListeningPoint(transport); 357600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 358600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String dialogId = sipRequest.getDialogId(false); 359600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPDialog dialog = sipStack.getDialog(dialogId); 360600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog != null && dialog.getState() == DialogState.TERMINATED) { 361600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 362600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // throw new TransactionUnavailableException 363600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // ("Found a terminated dialog -- possible re-use of old tag 364600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // parameters"); 365600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.removeDialog(dialog); 366600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 367600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 368600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 369600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // An out of dialog route was found. Assign this to the 370600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // client transaction. 371600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 372600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 373600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Set the brannch id before you ask for a tx. 374600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // If the user has set his own branch Id and the 375600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // branch id starts with a valid prefix, then take it. 376600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // otherwise, generate one. If branch ID checking has 377600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // been requested, set the branch ID. 378600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String branchId = null; 379600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipRequest.getTopmostVia().getBranch() == null 380600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang || !sipRequest.getTopmostVia().getBranch().startsWith( 381600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPConstants.BRANCH_MAGIC_COOKIE) 382600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang || sipStack.checkBranchId() ) { 383600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang branchId = Utils.getInstance().generateBranchId(); 384600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 385600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipRequest.getTopmostVia().setBranch(branchId); 386600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 387600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Via topmostVia = sipRequest.getTopmostVia(); 388600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 389600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang //set port and transport if user hasn't already done this. 390600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if(topmostVia.getTransport() == null) 391600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang topmostVia.setTransport(transport); 392600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 393600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if(topmostVia.getPort() == -1) 394600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang topmostVia.setPort(listeningPoint.getPort()); 395600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang branchId = sipRequest.getTopmostVia().getBranch(); 396600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 397600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPClientTransaction ct = (SIPClientTransaction) sipStack 398600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .createMessageChannel(sipRequest, listeningPoint 399600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getMessageProcessor(), hop); 400600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (ct == null) 401600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException("Cound not create tx"); 402600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ct.setNextHop(hop); 403600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ct.setOriginalRequest(sipRequest); 404600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ct.setBranch(branchId); 405600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // if the stack supports dialogs then 406600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isDialogCreated(request.getMethod())) { 407600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // create a new dialog to contain this transaction 408600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // provided this is necessary. 409600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // This could be a re-invite 410600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // in which case the dialog is re-used. 411600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // (but noticed by Brad Templeton) 412600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog != null) 413600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ct.setDialog(dialog, sipRequest.getDialogId(false)); 414600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else if (this.isAutomaticDialogSupportEnabled()) { 415600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPDialog sipDialog = sipStack.createDialog(ct); 416600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ct.setDialog(sipDialog, sipRequest.getDialogId(false)); 417600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 418600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 419600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog != null) { 420600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ct.setDialog(dialog, sipRequest.getDialogId(false)); 421600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 422600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 423600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 424600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 425600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // The provider is the event listener for all transactions. 426600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ct.addEventListener(this); 427600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return (ClientTransaction) ct; 428600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IOException ex) { 429600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 430600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 431600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Could not resolve next hop or listening point unavailable! ", 432600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ex); 433600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 434600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (java.text.ParseException ex) { 435600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex); 436600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 437600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Unexpected Exception FIXME! ", ex); 438600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (InvalidArgumentException ex) { 439600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex); 440600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 441600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Unexpected Exception FIXME! ", ex); 442600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 443600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 444600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 445600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 446600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 447600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 448600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 449600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#getNewServerTransaction(javax.sip.message.Request) 450600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 451600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public ServerTransaction getNewServerTransaction(Request request) 452600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throws TransactionAlreadyExistsException, 453600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TransactionUnavailableException { 454600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 455600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!sipStack.isAlive()) 456600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException("Stack is stopped"); 457600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPServerTransaction transaction = null; 458600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPRequest sipRequest = (SIPRequest) request; 459600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 460600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipRequest.checkHeaders(); 461600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (ParseException ex) { 462600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException(ex.getMessage(), ex); 463600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 464600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 465600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( request.getMethod().equals(Request.ACK)) { 466600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( sipStack.isLoggingEnabled()) 467600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logError("Creating server transaction for ACK -- makes no sense!"); 468600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException("Cannot create Server transaction for ACK "); 469600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 470600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 471600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Got a notify. 472600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 473600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipRequest.getMethod().equals(Request.NOTIFY) 474600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && sipRequest.getFromTag() != null 475600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && sipRequest.getToTag() == null) { 476600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 477600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPClientTransaction ct = sipStack.findSubscribeTransaction( 478600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipRequest, (ListeningPointImpl) this.getListeningPoint()); 479600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* Issue 104 */ 480600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (ct == null && ! sipStack.deliverUnsolicitedNotify) { 481600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 482600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Cannot find matching Subscription (and gov.nist.javax.sip.DELIVER_UNSOLICITED_NOTIFY not set)"); 483600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 484600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 485600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( !sipStack.acquireSem()) { 486600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 487600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Transaction not available -- could not acquire stack lock"); 488600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 489600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 490600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isDialogCreated(sipRequest.getMethod())) { 491600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.findTransaction((SIPRequest) request, true) != null) 492600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionAlreadyExistsException( 493600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "server transaction already exists!"); 494600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 495600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction = (SIPServerTransaction) ((SIPRequest) request) 496600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getTransaction(); 497600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction == null) 498600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 499600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Transaction not available"); 500600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction.getOriginalRequest() == null) 501600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.setOriginalRequest(sipRequest); 502600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 503600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.addTransaction(transaction); 504600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IOException ex) { 505600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 506600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Error sending provisional response"); 507600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 508600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // So I can handle timeouts. 509600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.addEventListener(this); 510600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (isAutomaticDialogSupportEnabled()) { 511600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // If automatic dialog support is enabled then 512600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // this tx gets his own dialog. 513600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String dialogId = sipRequest.getDialogId(true); 514600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPDialog dialog = sipStack.getDialog(dialogId); 515600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog == null) { 516600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog = sipStack.createDialog(transaction); 517600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 518600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 519600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.setDialog(dialog, sipRequest.getDialogId(true)); 520600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipRequest.getMethod().equals(Request.INVITE) && this.isDialogErrorsAutomaticallyHandled()) { 521600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.putInMergeTable(transaction, sipRequest); 522600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 523600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addRoute(sipRequest); 524600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog.getRemoteTag() != null 525600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && dialog.getLocalTag() != null) { 526600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.sipStack.putDialog(dialog); 527600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 528600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 529600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 530600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 531600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (isAutomaticDialogSupportEnabled()) { 532600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 533600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Under automatic dialog support, dialog is tied into a transaction. You cannot 534600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * create a server tx except for dialog creating transactions. After that, all 535600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * subsequent transactions are created for you by the stack. 536600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 537600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction = (SIPServerTransaction) sipStack.findTransaction( 538600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang (SIPRequest) request, true); 539600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction != null) 540600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionAlreadyExistsException( 541600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Transaction exists! "); 542600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction = (SIPServerTransaction) ((SIPRequest) request) 543600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getTransaction(); 544600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction == null) 545600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 546600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Transaction not available!"); 547600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction.getOriginalRequest() == null) 548600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.setOriginalRequest(sipRequest); 549600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Map the transaction. 550600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 551600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.addTransaction(transaction); 552600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IOException ex) { 553600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 554600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Could not send back provisional response!"); 555600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 556600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 557600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // If there is a dialog already assigned then just update the 558600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // dialog state. 559600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String dialogId = sipRequest.getDialogId(true); 560600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPDialog dialog = sipStack.getDialog(dialogId); 561600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog != null) { 562600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addTransaction(transaction); 563600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addRoute(sipRequest); 564600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.setDialog(dialog, sipRequest.getDialogId(true)); 565600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 566600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 567600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 568600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction = (SIPServerTransaction) sipStack.findTransaction( 569600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang (SIPRequest) request, true); 570600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction != null) 571600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionAlreadyExistsException( 572600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Transaction exists! "); 573600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction = (SIPServerTransaction) ((SIPRequest) request) 574600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getTransaction(); 575600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction != null) { 576600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction.getOriginalRequest() == null) 577600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.setOriginalRequest(sipRequest); 578600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Map the transaction. 579600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.mapTransaction(transaction); 580600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 581600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // If there is a dialog already assigned then just 582600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // assign the dialog to the transaction. 583600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String dialogId = sipRequest.getDialogId(true); 584600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPDialog dialog = sipStack.getDialog(dialogId); 585600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog != null) { 586600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addTransaction(transaction); 587600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addRoute(sipRequest); 588600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.setDialog(dialog, sipRequest 589600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getDialogId(true)); 590600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 591600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 592600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return transaction; 593600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 594600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // tx does not exist so create the tx. 595600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 596600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang MessageChannel mc = (MessageChannel) sipRequest 597600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getMessageChannel(); 598600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction = sipStack.createServerTransaction(mc); 599600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction == null) 600600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new TransactionUnavailableException( 601600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Transaction unavailable -- too many servrer transactions"); 602600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 603600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.setOriginalRequest(sipRequest); 604600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.mapTransaction(transaction); 605600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 606600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // If there is a dialog already assigned then just 607600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // assign the dialog to the transaction. 608600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String dialogId = sipRequest.getDialogId(true); 609600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPDialog dialog = sipStack.getDialog(dialogId); 610600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog != null) { 611600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addTransaction(transaction); 612600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addRoute(sipRequest); 613600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang transaction.setDialog(dialog, sipRequest 614600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getDialogId(true)); 615600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 616600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 617600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return transaction; 618600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 619600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 620600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 621600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 622600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return transaction; 623600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } finally { 624600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.releaseSem(); 625600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 626600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 627600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 628600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 629600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 630600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 631600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 632600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#getSipStack() 633600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 634600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public SipStack getSipStack() { 635600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return (SipStack) this.sipStack; 636600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 637600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 638600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 639600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 640600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 641600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#removeSipListener(javax.sip.SipListener) 642600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 643600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void removeSipListener(SipListener sipListener) { 644600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipListener == this.getSipListener()) { 645600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.sipListener = null; 646600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 647600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 648600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang boolean found = false; 649600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 650600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (Iterator<SipProviderImpl> it = sipStack.getSipProviders(); it.hasNext();) { 651600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SipProviderImpl nextProvider = (SipProviderImpl) it.next(); 652600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (nextProvider.getSipListener() != null) 653600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang found = true; 654600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 655600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!found) { 656600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.sipListener = null; 657600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 658600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 659600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 660600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 661600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 662600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 663600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#sendRequest(javax.sip.message.Request) 664600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 665600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void sendRequest(Request request) throws SipException { 666600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!sipStack.isAlive()) 667600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("Stack is stopped."); 668600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 669600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // mranga: added check to ensure we are not sending empty (keepalive) 670600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // message. 671600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (((SIPRequest) request).getRequestLine() != null 672600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && request.getMethod().equals(Request.ACK)) { 673600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Dialog dialog = sipStack.getDialog(((SIPRequest) request) 674600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getDialogId(false)); 675600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog != null && dialog.getState() != null) { 676600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) 677600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logWarning( 678600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Dialog exists -- you may want to use Dialog.sendAck() " 679600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + dialog.getState()); 680600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 681600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 682600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Hop hop = sipStack.getRouter((SIPRequest) request).getNextHop(request); 683600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (hop == null) 684600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("could not determine next hop!"); 685600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPRequest sipRequest = (SIPRequest) request; 686600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Check if we have a valid via. 687600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Null request is used to send default proxy keepalive messages. 688600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ((!sipRequest.isNullRequest()) && sipRequest.getTopmostVia() == null) 689600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("Invalid SipRequest -- no via header!"); 690600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 691600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 692600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 693600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * JvB: Via branch should already be OK, dont touch it here? Some 694600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * apps forward statelessly, and then it's not set. So set only when 695600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * not set already, dont overwrite CANCEL branch here.. 696600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 697600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!sipRequest.isNullRequest()) { 698600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Via via = sipRequest.getTopmostVia(); 699600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String branch = via.getBranch(); 700600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (branch == null || branch.length() == 0) { 701600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang via.setBranch(sipRequest.getTransactionId()); 702600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 703600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 704600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang MessageChannel messageChannel = null; 705600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (this.listeningPoints.containsKey(hop.getTransport() 706600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .toUpperCase())) 707600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang messageChannel = sipStack.createRawMessageChannel( 708600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.getListeningPoint(hop.getTransport()).getIPAddress(), 709600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.getListeningPoint(hop.getTransport()).getPort(), hop); 710600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (messageChannel != null) { 711600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang messageChannel.sendMessage((SIPMessage) sipRequest,hop); 712600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 713600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException( 714600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Could not create a message channel for " 715600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + hop.toString()); 716600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 717600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IOException ex) { 718600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) { 719600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logException(ex); 720600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 721600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 722600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException( 723600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "IO Exception occured while Sending Request", ex); 724600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 725600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (ParseException ex1) { 726600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException(ex1); 727600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } finally { 728600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) 729600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug( 730600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "done sending " + request.getMethod() + " to hop " 731600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + hop); 732600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 733600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 734600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 735600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 736600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 737600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 738600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#sendResponse(javax.sip.message.Response) 739600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 740600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void sendResponse(Response response) throws SipException { 741600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!sipStack.isAlive()) 742600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("Stack is stopped"); 743600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPResponse sipResponse = (SIPResponse) response; 744600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Via via = sipResponse.getTopmostVia(); 745600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (via == null) 746600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("No via header in response!"); 747600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPServerTransaction st = (SIPServerTransaction) sipStack.findTransaction((SIPMessage)response, true); 748600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( st != null && st.getState() != TransactionState.TERMINATED && this.isAutomaticDialogSupportEnabled()) { 749600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("Transaction exists -- cannot send response statelessly"); 750600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 751600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String transport = via.getTransport(); 752600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 753600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // check to see if Via has "received paramaeter". If so 754600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // set the host to the via parameter. Else set it to the 755600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Via host. 756600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String host = via.getReceived(); 757600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 758600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (host == null) 759600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang host = via.getHost(); 760600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 761600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Symmetric nat support 762600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang int port = via.getRPort(); 763600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (port == -1) { 764600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang port = via.getPort(); 765600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (port == -1) { 766600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transport.equalsIgnoreCase("TLS")) 767600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang port = 5061; 768600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang else 769600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang port = 5060; 770600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 771600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 772600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 773600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // for correct management of IPv6 addresses. 774600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (host.indexOf(":") > 0) 775600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (host.indexOf("[") < 0) 776600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang host = "[" + host + "]"; 777600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 778600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Hop hop = sipStack.getAddressResolver().resolveAddress( 779600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang new HopImpl(host, port, transport)); 780600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 781600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang try { 782600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPointImpl listeningPoint = (ListeningPointImpl) this 783600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getListeningPoint(transport); 784600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (listeningPoint == null) 785600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException( 786600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "whoopsa daisy! no listening point found for transport " 787600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + transport); 788600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang MessageChannel messageChannel = sipStack.createRawMessageChannel( 789600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.getListeningPoint(hop.getTransport()).getIPAddress(), 790600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang listeningPoint.port, hop); 791600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang messageChannel.sendMessage(sipResponse); 792600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } catch (IOException ex) { 793600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException(ex.getMessage()); 794600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 795600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 796600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 797600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 798600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 799600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 800600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#setListeningPoint(javax.sip.ListeningPoint) 801600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 802600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized void setListeningPoint(ListeningPoint listeningPoint) { 803600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (listeningPoint == null) 804600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new NullPointerException("Null listening point"); 805600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPointImpl lp = (ListeningPointImpl) listeningPoint; 806600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang lp.sipProvider = this; 807600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String transport = lp.getTransport().toUpperCase(); 808600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.address = listeningPoint.getIPAddress(); 809600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.port = listeningPoint.getPort(); 810600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // This is the first listening point. 811600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.listeningPoints.clear(); 812600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.listeningPoints.put(transport, listeningPoint); 813600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 814600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 815600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 816600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 817600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 818600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 819600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#getNewDialog(javax.sip.Transaction) 820600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 821600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 822600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public Dialog getNewDialog(Transaction transaction) throws SipException { 823600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction == null) 824600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new NullPointerException("Null transaction!"); 825600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 826600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!sipStack.isAlive()) 827600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("Stack is stopped."); 828600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 829600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (isAutomaticDialogSupportEnabled()) 830600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException(" Error - AUTOMATIC_DIALOG_SUPPORT is on"); 831600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 832600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (!sipStack.isDialogCreated(transaction.getRequest().getMethod())) 833600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("Dialog cannot be created for this method " 834600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang + transaction.getRequest().getMethod()); 835600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 836600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPDialog dialog = null; 837600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPTransaction sipTransaction = (SIPTransaction) transaction; 838600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 839600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transaction instanceof ServerTransaction) { 840600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPServerTransaction st = (SIPServerTransaction) transaction; 841600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Response response = st.getLastResponse(); 842600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (response != null) { 843600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (response.getStatusCode() != 100) 844600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException( 845600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Cannot set dialog after response has been sent"); 846600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 847600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPRequest sipRequest = (SIPRequest) transaction.getRequest(); 848600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String dialogId = sipRequest.getDialogId(true); 849600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog = sipStack.getDialog(dialogId); 850600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog == null) { 851600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog = sipStack.createDialog((SIPTransaction) transaction); 852600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // create and register the dialog and add the inital route set. 853600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addTransaction(sipTransaction); 854600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addRoute(sipRequest); 855600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipTransaction.setDialog(dialog, null); 856600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 857600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 858600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipTransaction.setDialog(dialog, sipRequest.getDialogId(true)); 859600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 860600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipRequest.getMethod().equals(Request.INVITE) && this.isDialogErrorsAutomaticallyHandled()) { 861600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.putInMergeTable(st, sipRequest); 862600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 863600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 864600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 865600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPClientTransaction sipClientTx = (SIPClientTransaction) transaction; 866600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 867600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPResponse response = sipClientTx.getLastResponse(); 868600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 869600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (response == null) { 870600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // A response has not yet been received, then set this up as the 871600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // default dialog. 872600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPRequest request = (SIPRequest) sipClientTx.getRequest(); 873600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 874600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String dialogId = request.getDialogId(false); 875600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog = sipStack.getDialog(dialogId); 876600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialog != null) { 877600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException("Dialog already exists!"); 878600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 879600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog = sipStack.createDialog(sipTransaction); 880600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 881600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipClientTx.setDialog(dialog, null); 882600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 883600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 884600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new SipException( 885600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Cannot call this method after response is received!"); 886600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 887600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 888600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang dialog.addEventListener(this); 889600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return dialog; 890600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 891600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 892600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 893600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 894600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Invoked when an error has ocurred with a transaction. Propagate up to the 895600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * listeners. 896600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 897600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @param transactionErrorEvent 898600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Error event. 899600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 900600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void transactionErrorEvent( 901600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPTransactionErrorEvent transactionErrorEvent) { 902600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPTransaction transaction = (SIPTransaction) transactionErrorEvent 903600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .getSource(); 904600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 905600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (transactionErrorEvent.getErrorID() == SIPTransactionErrorEvent.TRANSPORT_ERROR) { 906600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // There must be a way to inform the TU here!! 907600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) { 908600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug( 909600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "TransportError occured on " + transaction); 910600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 911600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Treat this like a timeout event. (Suggestion from Christophe). 912600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Object errorObject = transactionErrorEvent.getSource(); 913600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Timeout timeout = Timeout.TRANSACTION; 914600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TimeoutEvent ev = null; 915600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 916600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (errorObject instanceof SIPServerTransaction) { 917600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ev = new TimeoutEvent(this, (ServerTransaction) errorObject, 918600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang timeout); 919600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 920600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPClientTransaction clientTx = (SIPClientTransaction) errorObject; 921600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Hop hop = clientTx.getNextHop(); 922600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( sipStack.getRouter() instanceof RouterExt ) { 923600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ((RouterExt) sipStack.getRouter()).transactionTimeout(hop); 924600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 925600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ev = new TimeoutEvent(this, (ClientTransaction) errorObject, 926600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang timeout); 927600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 928600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Handling transport error like timeout 929600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.handleEvent(ev, (SIPTransaction) errorObject); 930600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (transactionErrorEvent.getErrorID() == SIPTransactionErrorEvent.TIMEOUT_ERROR) { 931600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // This is a timeout event. 932600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Object errorObject = transactionErrorEvent.getSource(); 933600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Timeout timeout = Timeout.TRANSACTION; 934600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TimeoutEvent ev = null; 935600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 936600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (errorObject instanceof SIPServerTransaction) { 937600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ev = new TimeoutEvent(this, (ServerTransaction) errorObject, 938600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang timeout); 939600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 940600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPClientTransaction clientTx = (SIPClientTransaction) errorObject; 941600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Hop hop = clientTx.getNextHop(); 942600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( sipStack.getRouter() instanceof RouterExt ) { 943600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ((RouterExt) sipStack.getRouter()).transactionTimeout(hop); 944600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 945600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 946600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ev = new TimeoutEvent(this, (ClientTransaction) errorObject, 947600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang timeout); 948600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 949600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.handleEvent(ev, (SIPTransaction) errorObject); 950600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 951600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (transactionErrorEvent.getErrorID() == SIPTransactionErrorEvent.TIMEOUT_RETRANSMIT) { 952600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // This is a timeout retransmit event. 953600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // We should never get this if retransmit filter is 954600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // enabled (ie. in that case the stack should handle. 955600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // all retransmits. 956600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Object errorObject = transactionErrorEvent.getSource(); 957600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Transaction tx = (Transaction) errorObject; 958600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 959600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (tx.getDialog() != null) 960600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang InternalErrorHandler.handleException("Unexpected event !", 961600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.sipStack.getStackLogger()); 962600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 963600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Timeout timeout = Timeout.RETRANSMIT; 964600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang TimeoutEvent ev = null; 965600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 966600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (errorObject instanceof SIPServerTransaction) { 967600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ev = new TimeoutEvent(this, (ServerTransaction) errorObject, 968600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang timeout); 969600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 970600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ev = new TimeoutEvent(this, (ClientTransaction) errorObject, 971600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang timeout); 972600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 973600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.handleEvent(ev, (SIPTransaction) errorObject); 974600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 975600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 976600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 977600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 978600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 979600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see gov.nist.javax.sip.stack.SIPDialogEventListener#dialogErrorEvent(gov.nist.javax.sip.stack.SIPDialogErrorEvent) 980600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 981600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized void dialogErrorEvent(SIPDialogErrorEvent dialogErrorEvent) { 982600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang SIPDialog sipDialog = (SIPDialog) dialogErrorEvent.getSource(); 983600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang Reason reason = Reason.AckNotReceived; 984600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (dialogErrorEvent.getErrorID() == SIPDialogErrorEvent.DIALOG_ACK_NOT_SENT_TIMEOUT) { 985600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang reason= Reason.AckNotSent; 986600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else if (dialogErrorEvent.getErrorID() == SIPDialogErrorEvent.DIALOG_REINVITE_TIMEOUT) { 987600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang reason = Reason.ReInviteTimeout; 988600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 989600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (sipStack.isLoggingEnabled()) { 990600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang sipStack.getStackLogger().logDebug( 991600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Dialog TimeoutError occured on " + sipDialog); 992600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 993600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang DialogTimeoutEvent ev = new DialogTimeoutEvent(this, sipDialog, reason); 994600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // Handling transport error like timeout 995600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.handleEvent(ev, null); 996600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 997600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 998600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 999600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 1000600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 1001600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#getListeningPoints() 1002600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 1003600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized ListeningPoint[] getListeningPoints() { 1004600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1005600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPoint[] retval = new ListeningPointImpl[this.listeningPoints 1006600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .size()]; 1007600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.listeningPoints.values().toArray(retval); 1008600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return retval; 1009600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1010600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1011600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 1012600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 1013600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 1014600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#addListeningPoint(javax.sip.ListeningPoint) 1015600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 1016600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized void addListeningPoint(ListeningPoint listeningPoint) 1017600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throws ObjectInUseException { 1018600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPointImpl lp = (ListeningPointImpl) listeningPoint; 1019600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (lp.sipProvider != null && lp.sipProvider != this) 1020600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new ObjectInUseException( 1021600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Listening point assigned to another provider"); 1022600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang String transport = lp.getTransport().toUpperCase(); 1023600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (this.listeningPoints.isEmpty()) { 1024600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // first one -- record the IP address/port of the LP 1025600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1026600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.address = listeningPoint.getIPAddress(); 1027600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.port = listeningPoint.getPort(); 1028600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } else { 1029600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ((!this.address.equals(listeningPoint.getIPAddress())) 1030600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang || this.port != listeningPoint.getPort()) 1031600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new ObjectInUseException( 1032600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Provider already has different IP Address associated"); 1033600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1034600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1035600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (this.listeningPoints.containsKey(transport) 1036600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang && this.listeningPoints.get(transport) != listeningPoint) 1037600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new ObjectInUseException( 1038600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang "Listening point already assigned for transport!"); 1039600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1040600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang // This is for backwards compatibility. 1041600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang lp.sipProvider = this; 1042600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1043600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.listeningPoints.put(transport, lp); 1044600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1045600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1046600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1047600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 1048600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 1049600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 1050600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#removeListeningPoint(javax.sip.ListeningPoint) 1051600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 1052600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized void removeListeningPoint(ListeningPoint listeningPoint) 1053600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throws ObjectInUseException { 1054600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPointImpl lp = (ListeningPointImpl) listeningPoint; 1055600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if (lp.messageProcessor.inUse()) 1056600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang throw new ObjectInUseException("Object is in use"); 1057600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.listeningPoints.remove(lp.getTransport().toUpperCase()); 1058600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1059600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1060600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1061600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 1062600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * Remove all the listening points for this sip provider. This is called 1063600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * when the stack removes the Provider 1064600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 1065600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public synchronized void removeListeningPoints() { 1066600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang for (Iterator it = this.listeningPoints.values().iterator(); it 1067600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang .hasNext();) { 1068600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang ListeningPointImpl lp = (ListeningPointImpl) it.next(); 1069600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang lp.messageProcessor.stop(); 1070600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang it.remove(); 1071600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1072600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1073600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1074600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1075600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 1076600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 1077600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * 1078600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see javax.sip.SipProvider#setAutomaticDialogSupportEnabled(boolean) 1079600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 1080600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void setAutomaticDialogSupportEnabled( 1081600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang boolean automaticDialogSupportEnabled) { 1082600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.automaticDialogSupportEnabled = automaticDialogSupportEnabled; 1083600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang if ( this.automaticDialogSupportEnabled ) { 1084600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.dialogErrorsAutomaticallyHandled = true; 1085600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1086600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1087600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1088600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 1089600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @return Returns the automaticDialogSupportEnabled. 1090600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 1091600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public boolean isAutomaticDialogSupportEnabled() { 1092600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return automaticDialogSupportEnabled; 1093600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1094600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1095600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /* 1096600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * (non-Javadoc) 1097600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @see gov.nist.javax.sip.SipProviderExt#setDialogErrorsAutomaticallyHandled() 1098600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 1099600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public void setDialogErrorsAutomaticallyHandled() { 1100600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang this.dialogErrorsAutomaticallyHandled = true; 1101600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1102600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1103600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public boolean isDialogErrorsAutomaticallyHandled() { 1104600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return this.dialogErrorsAutomaticallyHandled; 1105600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1106600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1107600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1108600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang /** 1109600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang * @return the sipListener 1110600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang */ 1111600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang public SipListener getSipListener() { 1112600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang return sipListener; 1113600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang } 1114600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1115600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang 1116600c7a4bbc7348167293eac928192e695b4ad5baChung-yih Wang} 1117