/** * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Unpublished - rights reserved under the Copyright Laws of the United States. * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. * Copyright © 2005 BEA Systems, Inc. All rights reserved. * * Use is subject to license terms. * * This distribution may include materials developed by third parties. * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Module Name : JSIP Specification * File Name : SipProvider.java * Author : Phelim O'Doherty * * HISTORY * Version Date Author Comments * 1.1 08/10/2002 Phelim O'Doherty Reworked * 1.2 05/03/2005 M. Ranganathan getNewDialog method added. * 1.2 07/07/2005 Phelim O'Doherty Added add/removeListeningPoint methods * Added getListeningPoints method * Removed restriction that a SipProvider * can only have a single ListeningPoint * 1.2 09/07/2005 M. Ranganathan Added getListeningPoint( String transport) * *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ package javax.sip; import java.util.*; import javax.sip.message.*; import javax.sip.header.*; /** * This interface represents the messaging entity of a SIP stack and as such is * the interface that defines the messaging and transactional component view of * the SIP stack. It must be implemented by any object representing a SIP stack * compliant to this specification that interacts directly with a proprietary * implementation of a SIP stack. This interface defines the methods that enable * any registered application implementing the {@link javax.sip.SipListener} * interface to: * *

* Architecture:
* This specification defines a many-to-one relationship between a SipProvider * and a SipStack, a one-to-many relationship between a SipProvider and a * ListeningPoint and a many-to-one relationship between a SipProvider and a * SipListener. *

* Each SipProvider can be related to zero or more ListeningPoints. However, the * SipProvider can have only one ListeningPoint for each transport type. For * example, a single SipProvider can have one TCP ListeningPoint and one UDP * ListeningPoint but cannot have two UDP ListeningPoints. Application that * wishes to have multiple ListeningPoints with the same transport must use a * separate SipProvider for each such ListeningPoint. *

* The ListeningPoints of the SipProvider specify the local address from where * request messages will be sent. When the application sends a request directly * from a SipProvider or from an object that the SipProvider created (Dialog or * Transaction) the application might not know in advance the transport that * this request will use. The transport is often resolved using a DNS server. In * the process of sending the request, the remote transport will be resolved. * The provider will then be able to send the request from a suitable * ListeningPoint according to the resolved transport. If the resolved transport * is UDP, the Provider's UDP ListeningPoint will be used. If the resolved * address is TCP, the Providers's TCP ListeningPoint will be used. *

* If the application creates a SipProvider with a single ListeningPoint, let's * say UDP, it means that UDP requests will be sent from the specific UDP * ListeningPoint, and that the application does not care from where TCP * requests will be sent. This is left for the SipStack decision. *

* Since the transport might not be known in advance, the application might find * it difficult to specify the transport in the Via header. The SipProvider is * responsible for fixing the Via header transport if needed. If the application * set a sent-by identifier to the ListeningPoint that is different then the * sent-by parameter in the message, the sent-by parameter of the message will * be updated. *

* If the application created a provider with zero ListeningPoint, it must have * only a single SipProvider per SipStack. *

* * A SipProvider has the capability to behave transaction statefully, dialog * statefully and statelessly. The transaction stateful methods are defined on * the ClientTransaction and ServerTransaction respectfully. The transaction * stateful method defined specifically for UAC and stateful proxy applications * is: *

*

* The stateful (transactional) convenience method defined specifically for UAS * and stateful proxy applications is: *

*

* The dialog stateful methods defined specifically for UAC and stateful proxy * applications are: *

*

* The stateless methods (non-transactional) defined on the SipProvider are: *

*

* Transaction Model:
* This specification supports stateful and stateless applications on a per * message basis, hence transactional semantics are not mandated for all * messages. This specification defines two types of transactions, server * transactions and client transactions. A stateless proxy does not contain a * client or server transaction, stateless proxies are effectively transparent * with respect to transactions. *

* Client Transaction:
* A client transaction exists between a UAC and a UAS specific to Request * messages and a server transaction exists between a UAS and a UAC specific to * Response messages. A transaction either server or client identifies messages * sent between two SIP entities. The purpose of a client transaction is to * identify a Request sent by an application that will reliably deliver the * Request to a server transaction on the responding SIP entity. The purpose of * a server transaction is to identify a Response sent by an application that * will reliably deliver the Response to the request initiator. *

* Server Transaction:
* A new server transaction is required for each response that an application * decides to respond to statefully, as follows: *

*

* Sending Requests:
* The client side of the transport layer is responsible for sending the * request. The application passes the the Request to the ClientTransaction * Dialog or the SipProvider that will send the Request over one of the * SipProvider's ListeningPoints. The SipProvider will choose a ListeningPoint * that has the same transport as the destination. For example, a Request that * is going to be sent over TCP will use a TCP ListeningPoint. See section * 18.1.1 of RFC3261. *

* Sending Responses:
* The server side of the transport layer is responsible for sending the * responses. The application passes the Response to the ServerTransaction or * the SipProvider that will send the Response over one of its ListeningPoints. * RFC3261. The response * must be sent from the same ListeningPoint on which the request was received. *

* Receiving Requests:
* A SipProvider should be prepared to receive requests on any IP address, port * and transport encapsulated in one of its ListeningPoints. When the * SipProvider receives a request over any transport, it must examine the value * of the "sent-by" parameter in the top Via header. If the host portion of the * "sent-by" parameter contains a domain name, or if it contains an IP address * that differs from the packet source address, the server must add a "received" * parameter to that Via header field value. This parameter must contain the * source address from which the packet was received. This is to assist the * SipProvider in sending the response, since it must be sent to the source IP * address from which the request came. Next, the SipProvider attempts to match * the request to a server transaction. If there are any server transactions in * existence, the server transport uses the matching procedures of Chapter 17 of * RFC3261 to attempt to * match the response to an existing transaction. If a matching server * transaction is found, the request is passed to that transaction, encapsulated * into a RequestEvent and fired to the application for processing. If no match * is found, the request is passed to the application, which may decide to * construct a new server transaction for that request. *

* Receiving Responses
* Responses are first processed by the transport layer and then passed up to * the transaction layer. The transaction layer performs its processing and then * passes the response up to the application. When a response is received, the * SipProvider examines the top Via header. If the value of the "sent-by" * parameter in that header field value does not correspond to a value that the * client transport is configured to insert into requests, the response MUST be * silently discarded. If there are any client transactions in existence, the * client transport uses the matching procedures of Chapter 17 of RFC3261 to attempt to match the * response to an existing transaction. If there is a match, the response must * be passed to that transaction, encapsulated into a ResponseEvent and fired to * the application. Otherwise, the response is stray and must be passed to the * application to determine its outcome i.e. a proxy will forward them, while a * User Agent will discard. * * @see SipListener * @see SipStack * * @author BEA Systems, Inc. * @author NIST * @version 1.2 */ public interface SipProvider { /** * This method registers the SipListener object to this SipProvider, once * registered the SIP Listener recieve events emitted from the SipProvider. * This specification restricts a unicast Listener model, that is only one * Listener may be registered on the SipProvider. If an attempt is made to * re-register the existing registered SipListener this method returns * silently. * * @param sipListener * the SipListener to be registered with the SipProvider. * @throws TooManyListenersException * when a new SipListener attempts to register with the * SipProvider when another SipListener is already registered * with this SipProvider. */ public void addSipListener(SipListener sipListener) throws TooManyListenersException; /** * Removes the specified SipListener from this SipProvider. This method * returns silently if the SipListener is not registered with the * SipProvider. * * @param sipListener * the SipListener to be removed from this SipProvider. */ public void removeSipListener(SipListener sipListener); /** * Returns the SipStack that created this SipProvider. A SipProvider can * only be attached to a single SipStack object that belongs to the same * implementation as this SipProvider. * * @see SipStack * @return the SipStack that created this SipProvider. */ public SipStack getSipStack(); /** * Returns the ListeningPoint of this SipProvider. A SipProvider has a * single Listening Point at any specific point in time. * * @deprecated since v1.2 - Note that in v1.1 a SipProvider could only be * associated to a single listening point, this restriction has * been lifted to allow a SipProvider to have a specific * ListeningPoints for each transport. For backwards * compatibility, this method will return the first * ListeningPoint of the list of ListeningPoints associated with * the SipProvider. This method has been replaced with * {@link SipProvider#getListeningPoints()}. * */ public ListeningPoint getListeningPoint(); /** * Returns all the ListeningPoints of this SipProvider. A SipProvider may * have a Listening Point for each specific transport type at any specific * point in time. A SipProvider must use the same transport for sending * responses that was used for sending the outbound request. * * @return an array of ListeningPoints associated to this SipProvider. * @since v1.2 */ public ListeningPoint[] getListeningPoints(); /** * This method sets the ListeningPoint of the SipProvider. * * @deprecated since v1.2 - Note that in v1.1 a SipProvider could only be * associated to a single listening point, this restriction has * been lifted to allow a SipProvider to have a specific * ListeningPoints for each transport. For backwards * compatibility, this method will add the ListeningPoint to the * list of ListeningPoints associated with the SipProvider. This * method has been replaced with * {@link SipProvider#addListeningPoint(ListeningPoint)}, the * same semantics apply to this method. */ public void setListeningPoint(ListeningPoint listeningPoint) throws ObjectInUseException; /** * This method adds the supplied ListeningPoint to the list of * ListeningPoints associated to this SipProvider. A SipProvider can only * have a single ListeningPoint for each transport type at any specific * time. Multiple SipProviders are prohibited to listen on the same * ListeningPoints. This method returns silently if the same ListeningPoint * argument is re-set on the SipProvider. If there is a ListeningPoint with * the same transport but different IP or port, the implementation is * expected to throw an exception. * * @param listeningPoint - * the listening point to add to this ListeningPoint * @throws ObjectInUseException * if the supplied ListeningPoint is being used by another * SipProvider or if there is already a LP for the given * transport. * @throws TransportAlreadySupportedException * if there is already a ListeningPoint associated to this * SipProvider with the same transport of the ListeningPoint. * * @since v1.2 */ public void addListeningPoint(ListeningPoint listeningPoint) throws ObjectInUseException, TransportAlreadySupportedException; /** * Get the listening point for a given transport. Null is returned if there * is no listening point for that transport. * * @param transport -- * the transport for the listening point * * @since v1.2 */ public ListeningPoint getListeningPoint(String transport); /** * Removes the specified ListeningPoint from this SipProvider. This method * returns silently if the ListeningPoint is not associated to this * SipProvider. A SipProvider must have at least a single ListeningPoint at * all times. When the ListeningPoint is removed the SipProvider no further * requests will be sent out over this ListeningPoint. * * @param listeningPoint * the ListenPoint to be removed from this SipProvider. * @throws ObjectInUseException * if the ListeningPoint is already in use or is the last * ListeningPoint associated with this SipProvider. * @since v1.2 */ public void removeListeningPoint(ListeningPoint listeningPoint) throws ObjectInUseException; /** * Returns a unique CallIdHeader for identifying dialogues between two SIP * applications. * * @return the new CallIdHeader unique within the SipProvider. */ public CallIdHeader getNewCallId(); /** * Before an application can send a new request it must first request a new * client transaction to handle that Request. This method is called by the * application to create the new client transaction befores it sends the * Request on that transaction. This methods returns a new unique client * transaction that can be passed to send Requests statefully. * * @param request * the new Request message that is to handled statefully by the * ClientTransaction. * @return a new unique client transaction. * @throws TransactionUnavailableException * if a new transaction can not be created, for example the next * hop of the request can not be determined. * @see ClientTransaction * @since v1.1 */ public ClientTransaction getNewClientTransaction(Request request) throws TransactionUnavailableException; /** * An application has the responsibility of deciding to respond to a Request * that does not match an existing server transaction. This method is called * by an application that decides to respond to an unmatched Request * statefully. This methods return a new unique server transaction that can * be used to respond to the request statefully. * * @param request * the Request message that the doesn't match an existing * transaction that the application decides to handle statefully. * @return a new unique server transaction. * @throws TransactionAlreadyExistsException * if a transaction already exists that is already handling this * Request. This may happen if the application gets retransmits * of the same request before the initial transaction is * allocated. * @throws TransactionUnavailableException * if a new transaction can not be created, for example the next * hop of the request can not be determined. * @see ServerTransaction * @since v1.1 */ public ServerTransaction getNewServerTransaction(Request request) throws TransactionAlreadyExistsException, TransactionUnavailableException; /** * Sends the Request statelessly, that is no transaction record is * associated with this action. This method implies that the application is * functioning as a stateless proxy, hence the underlying SipProvider acts * statelessly. A stateless proxy simply forwards every request it receives * downstream and discards information about the Request message once the * message has been forwarded. A stateless proxy does not have any notion of * a transaction. *

* Once the Request message has been passed to this method, the SipProvider * will forget about this Request. No transaction semantics will be * associated with the Request and the SipProvider will not handle * retranmissions for the Request. If these semantics are required it is the * responsibility of the application not the SipProvider. * * @since v1.1 * @see Request * @param request * the Request message to send statelessly * @throws SipException * if the SipProvider cannot send the Request for any reason. */ public void sendRequest(Request request) throws SipException; /** * Sends the Response statelessly, that is no transaction record is * associated with this action. This method implies that the application is * functioning as either a stateless proxy or a stateless UAS. *

* * @see Response * @param response * the Response to send statelessly. * @throws SipException * if the SipProvider cannot send the Response for any reason. * @see Response * @since v1.1 */ public void sendResponse(Response response) throws SipException; /** * Create a dialog for the given transaction. This method is only called * when AUTOMATIC_DIALOG_SUPPORT is off. This method is invoked when the * application wants to explicitly manage the association between * transaction and dialog. This must may only be called on a dialog-creating * transaction. Dialogs are created in advance, before any responses are * sent or received, using the initial client or server transaction. The * Dialog state is set to null when the dialog is created. The server side * of a dialog calls this method before sending out the response to a dialog * creating request. The client side of the dialog calls this method before * sending out the initial request via the dialog creating transaction. The * caller is required to set up the tags and other information in the * request/response before calling this method. * *

* For UAC's Forked calls are handled as follows: The response of a forked * call that completes the initially created dialog will use the original * dialog that is associated with the transaction. Subsequent responses that * correspond to other branches of the fork ( ie. with the same From header * tag, and Call ID but different To header tags) result in the creation of * additional dialogs that are associated with these responses. The created * dialog is made available to the UAC ( Listener ) via the method * ResponseEvent.getDialog * *

* Transactions that belong to the Dialog are automatically associated with * the Dialog by the stack and can be retrieved with * Transaction.getDialog(). * * * * @param transaction - * transaction that is used to extract the relevant information * to create the dialog. * * @throws SipException * if one or more of the following is true:
*

    *
  1. The Method of the Request is not a Dialog creating
  2. *
  3. There is missing required information such as From * header Tag in the Request
  4. *
  5. This method is called after the response recieved on the * client side
  6. *
  7. This method is called after the response is sent out on * the server side of the dialog.
  8. *
* * @since v1.2 */ public Dialog getNewDialog(Transaction transaction) throws SipException; /** * Enable or disable automatic dialog creation for this Provider. By * default, each provider inherits the automatic dialog support property * from the stack(i.e. the value implied by the stack configuration property * javax.sip.AUTOMATIC_DIALOG_SUPPORT) . This method allows for selective * overriding of the stack-wide property on a per provider basis. This is * useful for applications that need to support both user agent and proxy * functionality in a single stack such as IMS applications and 3rd party * call control. Provider instances that need to proxy requests while * functioning transaction statefully should turn this property off. * Provider instances that need to at as user agents can turn this support * on and get the benifit of automatic dialog creation. If this support is * enabled, then Dialog creating Transactions (i.e. INVITE) that are * associated with this Provider automatically create a Dialog when the * Transaction is created. If this support is disabled, then Transactions * associated with this Provider do not result in the automatic creation of * an associated Dialog at the time of Transaction creation. * * @param flag - enables or disables automatic dialog support for this provider. * * @see SipStack * @since v1.2 * */ public void setAutomaticDialogSupportEnabled(boolean flag); }