sip.SipListener Maven / Gradle / Ivy
/**
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 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 : SipListener.java
* Author : Phelim O'Doherty
*
* HISTORY
* Version Date Author Comments
* 1.1 08/10/2002 Phelim O'Doherty
* 1.2 02/15/2005 M. Ranganathan Added method for IO Exception
* 1.2 02/15/2005 M. Ranganathan Added method for TransactionTerminated
* propagation.
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
package javax.sip;
import java.util.EventListener;
/**
* This interface represents the application view to a SIP stack therefore
* defines the application's communication channel to the SIP stack. This
* interface defines the methods required by an applications to receive and
* process Events that are emitted by an object implementing the
* {@link javax.sip.SipProvider}interface.
*
* The Events accepted by a SipListener may be one of four types:
*
* - {@link RequestEvent}- these are request messages emitted as events by
* the SipProvider. Request events represent request messages i.e. INVITE, that
* are received from the network to the application via the underlying stack
* implementation.
*
- {@link ResponseEvent}- these are response messages emitted as events by
* the SipProvider. Response events represent Response messages i.e. 2xx's, that
* are received from the network to the application via the underlying stack
* implementation.
*
- {@link TimeoutEvent}- these are timeout notifications emitted as events
* by the SipProvider. Timeout events represent timers expiring in the
* underlying SipProvider transaction state machine. These timeout's events
* notify the application that a retranmission is required or a transaction has
* timed out.
*
- {@link IOExceptionEvent}- these are IO Exception notifications emitted as
* events by the SipProvider. IOException events represent failure in the
* underlying SipProvider IO Layer. These IO Exception events notify the
* application that a failure has occured while accessing a socket.
*
- {@link TransactionTerminatedEvent}- these are Transaction Terminated
* notifications emitted as events by the SipProvider. TransactionTerminated
* events represent a transaction termination and notify the
* application of the termination.
*
- {@link DialogTerminatedEvent}- these are Dialog Terminated
* notifications emitted as events by the SipProvider. DialogTerminated
* events represent a Dialog termination and notify the
* application of the termination.
*
*
* An application will only receive Request, Response, Timeout,
* TransactionTerminated, DialogTerminated and IOException
* events once it has registered as an EventListener of a SipProvider. The
* application registers with the SipProvider by invoking the
* {@link SipProvider#addSipListener(SipListener)}passing itself as an
* argument.
*
* Architecture:
* This specification mandates a single SipListener per SipStack,
* and a unicast event model i.e. a SipProvider can only have one SipListener
* registered with it. This specification allows multiple SipProviders per
* SipStack and as such a SipListener can register with multiple SipProviders
* i.e there is a one-to-many relationship between a SipListener and a SipProvider.
*
* Note: An application that implements the SipListener interface, may act as a
* proxy object and pass all events to higher level core application programming
* logic that is outside the scope of this specification. For example a SIP
* Servlet, or a JSLEE implementation can implement a back to back UA or
* Proxy core application respectively in there respective container
* environments utilizing this specification to talk the SIP protocol.
*
* Messaging Model:
* An application can send messages by passing {@link javax.sip.message.Request}
* and {@link javax.sip.message.Response}messages to that the following object:
*
* - Request and response messages can be sent statelessly via the
* SipProvider using the send methods on the {@link javax.sip.SipProvider}.
*
- Request messages can be sent transaction stateful via the
* ClientTransaction using the {@link ClientTransaction#sendRequest()}method.
*
- Response messages can be sent transaction stateful via the
* ServerTransaction using the {@link ServerTransaction#sendResponse(Response)}
* method.
*
- Request messages can be sent dialog stateful via the Dialog using the
* {@link Dialog#sendRequest(ClientTransaction)}method.
*
* Although this specification provides the capabilities to send messages both
* statelessly and statefully it is mandated that an application will not send
* the same message both statefully and statelessly.
* The messages sent by the application are not Event's as the event model is
* uni-directional from the SipProvider to the SipListener, i.e. the SipListener
* listens for Events from the SipProvider, but the SipProvider does not listen
* for Events on the SipListener. The rationale is the application knows when to
* initiate requests and responses i.e setup a call or respond to a network
* event, however an application doesn't know when it will receive a network
* event, hence the application must listen for these network events.
*
* Session Negotiation
* There are special rules for message bodies of Request and Responses that
* contain a session description. SIP uses an offer/answer model where one User
* Agent sends a session description, called the offer, which contains a
* proposed description of the session. The other User Agent responds with
* another session description, called the answer, which indicates which
* communications means are accepted. In this specification, offers and answers
* can only appear in INVITE requests and Responses, and ACK. The Session
* Description Protocol (SDP) RFC2327 MUST be supported by all
* user agents as a means to describe sessions, and its usage for constructing
* offers and answers MUST follow the procedures defined in RFC3261 . The SDP protocol is
* described in Java by JSR
* 141
*
* @see SipProvider
* @see RequestEvent
* @see ResponseEvent
* @see TimeoutEvent
* @see IOExceptionEvent
* @see TransactionTerminatedEvent
* @see DialogTerminatedEvent
*
* @author BEA Systems, NIST
* @version 1.2
*/
public interface SipListener extends EventListener {
/**
* Processes a Request received on a SipProvider upon which this SipListener
* is registered.
*
* Handling Requests:
* When the application receives a RequestEvent from the SipProvider the
* RequestEvent may or may not belong to an existing dialog of the
* application. The application can be determine if the RequestEvent belongs
* to an existing dialog by checking the server transaction of the
* RequestEvent.
*
* - If the server transaction equals
null
the
* RequestEvent does not belong to an existing dialog and the application
* must determine how to handle the RequestEvent. If the application decides
* to forward the Request statelessly no transactional support is required
* and it can simply pass the Request of the RequestEvent as an argument to
* the {@link SipProvider#sendRequest(Request)}method. However if the
* application determines to respond to a Request statefully it must request
* a new server transaction from the
* {@link SipProvider#getNewServerTransaction(Request)}method and use this
* server transaction to send the Response based on the content of the
* Request. If the SipProvider throws TransactionAlreadyExistsException when
* the application requests a new server transaction to handle a Request the
* current RequestEvent is a retransmission of the initial request from
* which the application hadn't requested a server transaction to handle it,
* i.e. this exception handles the race condition of an application
* informing the SipProvider that it will handle a Request and the receipt
* of a retransmission of the Request from the network to the SipProvider.
* - If the server transaction does NOT equal
null
* the application determines its action to the RequestEvent based on the
* content of the Request information.
*
*
* User Agent Server (UAS) Behaviour:
* A UAS application decides whether to accept the an invitation from a UAC.
* The UAS application can accept the invitation by sending a 2xx response
* to the UAC, a 2xx response to an INVITE transaction establishes a
* session. For 2xx responses, the processing is done by the UAS
* application, to guarantee the three way handshake of an INVITE
* transaction. This specification defines a utility thats enables the
* SipProvider to handle the 2xx processing for an INVITE transaction, see
* the {@link SipStack#isRetransmissionFilterActive()}method. If the
* invitation is not accepted, a 3xx, 4xx, 5xx or 6xx response is sent by
* the application, depending on the reason for the rejection. Alternatively
* before sending a final response, the UAS can also send provisional
* responses (1xx) to advise the UAC of progress in contacting the called
* user. A UAS that receives a CANCEL request for an INVITE, but has not yet
* sent a final response, would "stop ringing" and then respond to the
* INVITE with a specific 487 Error response.
*
* General Proxy behaviour:
* In some circumstances, a proxy application MAY forward requests using
* stateful transports without being transaction stateful, i.e. using the
* {@link SipProvider#sendRequest(Request)}method, but using TCP as a
* transport. For example, a proxy application MAY forward a request from
* one TCP connection to another transaction statelessly as long as it
* places enough information in the message to be able to forward the
* response down the same connection the request arrived on. This is the
* responsibility of the application and not the SipProvider. Requests
* forwarded between different types of transports where the proxy
* application takes an active role in ensuring reliable delivery on one of
* the transports must be forwarded using the stateful send methods on the
* SipProvider.
*
* Stateful Proxies:
* A stateful proxy MUST create a new server transaction for each new
* request received, either automatically generated by the SipProvider, if
* the request matches an existing dialog or by the an application call on
* the SipProvider if it decides to respond to the request statefully. The
* proxy application determines where to route the request, choosing one or
* more next-hop locations. An outgoing request for each next-hop location
* is processed by its own associated client transaction. The proxy
* application collects the responses from the client transactions and uses
* them to send responses to the server transaction. When an application
* receives a CANCEL request that matches a server transaction, a stateful
* proxy cancels any pending client transactions associated with a response
* context. A stateful proxy responds to the CANCEL rather than simply
* forwarding a response it would receive from a downstream element.
*
* For all new Requests, including any with unknown methods, an element
* intending to stateful proxy the Request determines the target(s) of the
* request. A stateful proxy MAY process the targets in any order. A
* stateful proxy must have a mechanism to maintain the target set as
* responses are received and associate the responses to each forwarded
* request with the original request. For each target, the proxy forwards
* the request following these steps:
*
* - Make a copy of the received request.
*
- Update the Request-URI.
*
- Update the Max-Forwards header.
*
- Optionally add a Record-route header.
*
- Optionally add additional headers.
*
- Postprocess routing information.
*
- Determine the next-hop address, port, and transport.
*
- Add a Via header.
*
- Add a Content-Length header if necessary.
*
- Forward the new request using the
* {@link ClientTransaction#sendRequest()}method.
*
- Process all responses recieved on the
* {@link SipListener#processResponse(ResponseEvent)}method.
*
- NOT generate 100 (Trying) responses to non-INVITE requests.
*
*
* A stateful proxy MAY transition to stateless operation at any time during
* the processing of a request, as long as it did nothing that would prevent
* it from being stateless initially i.e. forking or generation of a 100
* response. When performing such a transition, any state already stored is
* simply discarded.
*
* Forking Requests:
* A stateful proxy application MAY choose to "fork" a request, routing it
* to multiple destinations. Any request that is forwarded to more than one
* location MUST be forwarded using the stateful send methods on the
* SipProvider.
*
* Stateless Proxies:
* As a stateless proxy does not have any notion of a transaction, or of the
* response context used to describe stateful proxy behavior,
* requestEvent.getServerTransaction() == null;
always return
* true . The transaction layer of the SipProvider implementation
* is by-passed. For all requests including any with unknown methods, an
* application intending to stateless proxy the request MUST:
*
* - Validate the request.
*
- Preprocess routing information.
*
- Determine a single target(s) for the request.
*
- Forward the request to the target using the
* {@link SipProvider#sendRequest(Request)}method.
*
- NOT perform special processing for CANCEL requests.
*
*
* @param requestEvent -
* requestEvent fired from the SipProvider to the SipListener
* representing a Request received from the network.
*/
public void processRequest(RequestEvent requestEvent);
/**
* Processes a Response received on a SipProvider upon which this
* SipListener is registered.
*
* Handling Responses:
* When the application receives a ResponseEvent from the SipProvider the
* ResponseEvent may or may not correlate to an existing Request of the
* application. The application can be determine if the ResponseEvent
* belongs to an existing Request by checking the client transaction of the
* ResponseEvent.
*
* - If the the client transaction equals
null
the
* ResponseEvent does not belong to an existing Request and the Response is
* considered stray, i.e. stray response can be identitied, if
* responseEvent.getClientTransaction() == null;
. Handling
* of these "stray" responses is dependent on the application i.e. a proxy
* will forward them statelessly using the
* {@link SipProvider#sendResponse(Response)}method, while a User Agent
* will discard them.
* - If the client transaction does NOT equal
null
* the application determines it action to the ResponseEvent based on the
* content of the Response information.
*
*
* User Agent Client (UAC) behaviour:
* After possibly receiving one or more provisional responses (1xx) to a
* Request, the UAC will get one or more 2xx responses or one non-2xx final
* response. Because of the protracted amount of time it can take to receive
* final responses to an INVITE, the reliability mechanisms for INVITE
* transactions differ from those of other requests. A UAC needs to send an
* ACK for every final Response it receives, however the procedure for
* sending the ACK depends on the type of Response. For final responses
* between 300 and 699, the ACK processing is done by the transaction layer
* i.e. handled by the implementation. For 2xx responses, the ACK processing
* is done by the UAC application, to guarantee the three way handshake of
* an INVITE transaction. This specification defines a utility thats enables
* the SipProvider to handle the ACK processing for an INVITE transaction,
* see the {@link SipStack#isRetransmissionFilterActive()}method.
* A 2xx response to an INVITE establishes a session, and it also creates a
* dialog between the UAC that issued the INVITE and the UAS that generated
* the 2xx response. Therefore, when multiple 2xx responses are received
* from different remote User Agents, i.e. the INVITE forked, each 2xx
* establishes a different dialog and all these dialogs are part of the same
* call. If an INVITE client transaction returns a {@link TimeoutEvent}
* rather than a response the UAC acts as if a 408 (Request Timeout)
* response had been received from the UAS.
*
* Stateful Proxies:
* A proxy application that handles a response statefully must do the
* following processing:
*
* - Find the appropriate response context.
*
- Remove the topmost Via header.
*
- Add the response to the response context.
*
- Check to determine if this response should be forwarded immediately.
*
- When necessary, choose the best final response from the response
* context. If no final response has been forwarded after every client
* transaction associated with the response context has been terminated, the
* proxy must choose and forward the "best" response from those it has seen
* so far.
*
*
* Additionally the following processing MUST be performed on each response
* that is forwarded.
*
* - Aggregate authorization header values if necessary.
*
- Optionally rewrite Record-Route header values.
*
- Forward the response using the
* {@link ServerTransaction#sendResponse(Response)}method.
*
- Generate any necessary CANCEL requests.
*
*
* Stateless Proxies:
* As a stateless proxy does not have any notion of transactions, or of the
* response context used to describe stateful proxy behavior,
* responseEvent.getClientTransaction == null;
always return
* true . Response processing does not apply, the transaction
* layer of the SipProvider implementation is by-passed. An application
* intending to stateless proxy the Response MUST:
*
* - Inspect the sent-by value in the first Via header.
*
- If that address matches the proxy, the proxy MUST remove that header
* from the response.
*
- Forward the resulting response to the location indicated in the next
* Via header using the {@link SipProvider#sendResponse(Response)}method.
*
*
* @param responseEvent -
* the responseEvent fired from the SipProvider to the
* SipListener representing a Response received from the network.
*/
public void processResponse(ResponseEvent responseEvent);
/**
* Processes a retransmit or expiration Timeout of an underlying
* {@link Transaction}handled by this SipListener. This Event notifies the
* application that a retransmission or transaction Timer expired in the
* SipProvider's transaction state machine. The TimeoutEvent encapsulates
* the specific timeout type and the transaction identifier either client or
* server upon which the timeout occured. The type of Timeout can by
* determined by:
* timeoutType = timeoutEvent.getTimeout().getValue();
*
* @param timeoutEvent -
* the timeoutEvent received indicating either the message
* retransmit or transaction timed out.
*/
public void processTimeout(TimeoutEvent timeoutEvent);
/**
* Process an asynchronously reported IO Exception. Asynchronous IO
* Exceptions may occur as a result of errors during retransmission of
* requests. The transaction state machine requires to report IO Exceptions
* to the application immediately (according to RFC 3261). This method
* enables an implementation to propagate the asynchronous handling of IO
* Exceptions to the application.
*
* @since v1.2
* @param exceptionEvent --
* The Exception event that is reported to the application.
*/
public void processIOException(IOExceptionEvent exceptionEvent);
/**
* Process an asynchronously reported TransactionTerminatedEvent.
* When a transaction transitions to the Terminated state, the stack
* keeps no further records of the transaction. This notification can be used by
* applications to clean up any auxiliary data that is being maintained
* for the given transaction.
*
* @param transactionTerminatedEvent -- an event that indicates that the
* transaction has transitioned into the terminated state.
* @since v1.2
*/
public void processTransactionTerminated(TransactionTerminatedEvent
transactionTerminatedEvent);
/**
* Process an asynchronously reported DialogTerminatedEvent.
* When a dialog transitions to the Terminated state, the stack
* keeps no further records of the dialog. This notification can be used by
* applications to clean up any auxiliary data that is being maintained
* for the given dialog.
*
* @param dialogTerminatedEvent -- an event that indicates that the
* dialog has transitioned into the terminated state.
* @since v1.2
*/
public void processDialogTerminated(DialogTerminatedEvent
dialogTerminatedEvent);
}