The Source for Java Technology Collaboration


Update page.

This wiki page is outdated, see one Here, for more info about implementation look Here

Sip RA Type Memo

Abstract

This is a description of an extension of the SIP RA Type (as recommended in JAIN SLEE 1.0) supporting SIP dialogs. The goal is to specify a SIP RA Type to significantly simplify writing JSLEE applications using SIP dialogs. This is a community effort to agree on a dialog extension that can later be standardised via JCP.

Definitions

Mid-dialog request := A request starting a new transaction within an already established dialog, as described in RFC 3261 section 12.2. Examples are re-INVITEs, BYE, MESSAGE.

Out-of-dialog request := A request that it sent outside an existing dialog. The most common example is an original INVITE which can lead to a dialog being created but which is by definition sent before any dialog exists.

SIP RA Type with dual event sets

Introduction

This is a description of the strategy adopted by Open Cloud which in short amounts to defining dual events types for SIP requests that can occur either as mid-dialog requests and out-of-dialog requests. As an example there are two event types that correspond to the MESSAGE request, which is used depends on whether there is a dialog ACI present or not. There are also additional event types for sip responses that have an impact on the corresponding dialog. For example the javax.sip.dialog.SetupConfirmed event is fired on a SIP OK response if there is a dialog ACI. The rationale for this is that the impact of the sip response is of greater interest for the application than the actual sip response.

Activities and Sip RA interfaces

There is one new activity, javax.sip.Dialog, and the old activities remain the same (javax.sip.ClientTransaction, javax.sip.ServerTransaction). The SipActivityContextInterfaceFactory is extended with the follwing method:

public ActivityContextInterface getActivityContextInterface(javax.sip.Dialog dialog) throws NullPointerException, UnrecognizedActivityException, FactoryException;

Table of events

Event ID (name,vendor,version) Class Activity Object Notes
Out of dialog requests - same as JAIN SIP 1.1 RA type
javax.sip.message.Request.INVITE, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction  
javax.sip.message.Request.ACK, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction (1)
javax.sip.message.Request.CANCEL, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction, INVITE or CANCEL transaction, depending on scenario, see Canceling request
javax.sip.message.Request.BYE, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.REGISTER, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.OPTIONS, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.PRACK, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.INFO, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.UPDATE, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.REFER, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.SUBSCRIBE, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.NOTIFY, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.MESSAGE, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction
javax.sip.message.Request.SIP_EXTENSION, javax.sip, 1.1 javax.sip.RequestEvent javax.sip.ServerTransaction (2)
In-dialog requests - new for 1.2 RA Type
javax.sip.dialog.Request.INVITE, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.ACK, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.BYE, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.REGISTER, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.OPTIONS, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.PRACK, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.INFO, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.UPDATE, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.REFER, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.SUBSCRIBE, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.NOTIFY, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.MESSAGE, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog
javax.sip.dialog.Request.SIP_EXTENSION, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog (2)
Responses - same as JAIN SIP 1.1 RA Type
javax.sip.message.Response.TRYING, javax.sip, 1.1 javax.sip.ResponseEvent javax.sip.ClientTransaction (3)
javax.sip.message.Response.INFORMATIONAL, javax.sip, 1.1 javax.sip.ResponseEvent javax.sip.ClientTransaction
javax.sip.message.Response.SUCCESS, javax.sip, 1.1 javax.sip.ResponseEvent javax.sip.ClientTransaction (1)
javax.sip.message.Response.REDIRECTION, javax.sip, 1.1 javax.sip.ResponseEvent javax.sip.ClientTransaction (1)
javax.sip.message.Response.CLIENT_ERROR, javax.sip, 1.1 javax.sip.ResponseEvent javax.sip.ClientTransaction (1)
javax.sip.message.Response.SERVER_ERROR, javax.sip, 1.1 javax.sip.ResponseEvent javax.sip.ClientTransaction (1)
javax.sip.message.Response.GLOBAL_FALIURE, javax.sip, 1.1 javax.sip.ResponseEvent javax.sip.ClientTransaction (1)
Timeouts
javax.sip.Timeout.TRANSACTION, javax.sip, 1.1 javax.sip.TimeoutEvent javax.sip.ClientTransaction/ javax.sip.ServerTransaction (1)
javax.sip.Timeout.DIALOG, net.java, 1.2 javax.sip.DialogTerminatedEvent javax.sip.Dialog (1)
Dialog State events - new for 1.2 RA Type
javax.sip.dialog.SetupEarly, net.java, 1.2 javax.sip.ResponseEvent javax.sip.Dialog (4)
javax.sip.dialog.SetupConfirmed, net.java, 1.2 javax.sip.ResponseEvent javax.sip.Dialog (4)
javax.sip.dialog.SetupFailed, net.java, 1.2 javax.sip.ResponseEvent javax.sip.Dialog (1,4)
javax.sip.dialog.SetupTimedOut, net.java, 1.2 javax.sip.TimeoutEvent javax.sip.Dialog (1,4)
javax.sip.dialog.Terminated, net.java, 1.2 javax.sip.DialogTerminatedEvent javax.sip.Dialog (1)
New for 1.2 RA Type
javax.sip.transaction.Terminated, net.java, 1.2 javax.sip.TransactionTerminatedEvent javax.sip.Transaction (one of transactions)
javax.sip.dialog.TerminationRequest, net.java, 1.2 javax.sip.RequestEvent javax.sip.Dialog (5) - fired when BYE request is received and dialog is terminated on receval of BYE
Notes:
  1. This event also ends the activity.
  2. This event is used when the request method is not recognized.
  3. This is just for "100 Trying" responses, which can usually be safely ignored by the app.
  4. These events will be fired instead of the usual response/timeout events, if a dialog activity exists.
  5. If a BYE request that terminates the dialog is received, the RA will fire a javax.sip.dialog.TerminationRequest event instead of a javax.sip.dialog.Request.BYE event.
A BYE does not always terminate the dialog (for example if subscriptions are still active). Similarly a Terminated event will be fired for a NOTIFY request with "Subscription-State: terminated" is received, and no other subscriptions or sessions are using the dialog.

Events and activities

The table of events contains four categories of events which are here described, motivated and illustrated with examples. Specifically the usage of dialog activities and transaction activities needs to be explained since they are coexisting and interrelated. This section describes the steps to be performed by the application code and specifies the behaviour of the RA in different situations.

Out-of-dialog request events

Delivered on a server transaction activity, these events make it explicit that it is an out-of-dialog request. Applications that do not need dialogs restrict themselves to this category of request events. When an out-of-dialog request event is fired with a dialog creating request method the application can opt to take advantage of the dialog support or just continue using the transaction based ACIs. Applications that want to take advantage of dialog support will do the following:

  • Obtain the javax.sip.Dialog object for the request which is done by calling the javax.sip.SipProvider.getNewDialog(Transaction tx) method. (The SipProvider is obtained from the JainSipResourceAdaptorSbbInterface)
  • Get the activity context interface by calling
    SipActivityContextInterfaceFactory.getActivityContextInterface(Dialog dialog)
  • Attach to the dialog ACI

Code snippet:

JainSipResourceAdaptorSbbInterface intf = ...
SipActivityContextInterfaceFactory factory = ...
SbbLocalObject myLocalObject = ...
SipProvider provider = intf.getSipProvider();
Dialog dialog = provider.getNewDialog(requestEvent.getServerTransaction());
ActivitiyContextInterface aci = factory.getActivityContextInterface(dialog);
aci.attach(myLocalObject);

From this point the following mid-dialog requests will be delivered on the dialog ACI. The RA does create server transaction activities for these requests and if the application needs to use the corresponding ACI it can obtain it by doing the following

ServerTransaction tx = RequestEvent.getServerTransaction();
SipActivityContextInterfaceFactory factory = ....
ActivityContextInterface aci = factory.getActivityContextInterface(tx);
Normally Sbbs should stay attached to the server transaction ACI corresponding to the out-of-dialog INVITE request initiating a dialog. This is because is the INVITE is cancelled this request is delivered on the same server transaction as the INVITE.

It is not necessary to create the dialog ACI and attach to it immediately after the dialog has been obtained. This step can be postponed to a later stage since the dialog object is obtainable from the javax.sip.RequestEvent , javax.sip.ResponseEvent and javax.sip.Transaction objects respectively. Hoever this is encouraged in cases when dialgo has not been created automaticly. Some implementations can depend on attaching to dialog ACI.

Mid-dialog request events

The events in this category mirror the events in the previous section but differ in that they are delivered on a dialog activity. This way the application writer can safely assume that the underlying activity is a dialog and act accordingly. A simple example is an Sbb that initiates a dialog and attaches to the dialog ACI . It will receive a subsequent re-INVITE on the dialog ACI . Note that if this Sbb also has has an event callback method for the javax.sip.message.Request.INVITE method this requires a separate method definition. This way it is easy to select what combinations of request method and dialog/transaction scope the Sbb will get events delivered for.

There are a few methods that deserve some extra explanation:

  • javax.sip.dialog.Request.ACK
This is used to acknowledge a 200 OK sent where the INVITE was itself delivered on a dialog ACI. Should there be a need to use the server transaction ACI this is possible by following the procedure described above.

  • javax.sip.dialog.Request.BYE
This is used in the case of a BYE which does not terminate the dialog. This happens if there are active subscriptions belonging to the dialog. For BYE and other requests that terminate a dialog the javax.sip.dialog.TerminationRequest event is used. This way the sip stack is adapted slightly to make it more convenient for applications focusing of the dialog state changes. Note that it is still possible to obtain the javax.sip.message.Request object that caused the event to be fired.

Automatic dialog creation

RA should support automatic dialog creation (however this feature should be optional - it has to have some on/off switch not to restrict use of indialog INVITEs if needed). This way sbb code will be simplified and programer will have to take care less about it. This can be achieved by adding to sbb-jar.xml event handler definition like following:

 <event event-direction="Receive" initial-event="True">
            <event-name>InDialogInvite</event-name>
            <event-type-ref>
                <event-type-name>javax.sip.dialog.Request.INVITE</event-type-name>
                <event-type-vendor>net.java</event-type-vendor>
                <event-type-version>1.2</event-type-version>
            </event-type-ref>
            ....
 </event>
This will notify RA that we would like to use dialogs. RA will send autoamtic 200 response to INVITE Request it has received, with generated toTag in order to fullfil all perequesites to create valid dialog. However if application wants to use dialogs but it is not interested in indialog re-INVITEs ( for instance rfc 4028 session refreshes) in can follow scenario mentioned above. This is done only for icoming requests. If local application is going to use dialog it has to follow scenario above.

Responses

This category is the same as for the JAIN SIP 1.1 RA Type and all events are delivered on client transaction activities. Applications that do not use dialogs relate only to this category for events caused by sip response messages (see below for clarification).

Applications that want to use the dialog support must obtain a dialog before a dialog creating request is sent (see the JAIN SIP 1.2 documentation). Code snippet:

JainSipResourceAdaptorSbbInterface intf = ...
SipActivityContextInterfaceFactory factory = ...
SbbLocalObject myLocalObject = ...
ClientTransaction tx = ....
SipProvider provider = intf.getSipProvider();
Dialog dialog = provider.getNewDialog(tx);
ActivitiyContextInterface aci = factory.getActivityContextInterface(dialog);
aci.attach(myLocalObject);

It is not mandatory to create and attach to the dialog ACI at this stage, this can be postponed to a later stage if desired. (But it is encouraged as soon as dialog representing object has been created) The code snippet shows the recommended way for most applications. If the Sbb is attached to the dialog ACI when the request is sent the behaviour of the RA is to deliver response events on a client transaction activity if the dialog state is not affected. For responses that affect the state of the dialog the events from the “Dialog state events” category are used. See next section for example flows containing both types of events.

Dialog state events

This category exists to aid applications that use dialogs, all events are delivered on dialog ACIs. For example, the RA will map multiple sip responses to one of the events in this category if they have the same effect on the dialog state. A concrete example is the error responses from the 400 – 600 series that are all mapped to the
javax.sip.dialog.SetupFailed event.

The dialog state is affected by responses, requests and timeouts and the following is a brief survey of the events.

When a provisional response with a To tag is received the dialog enters the early state and a

javax.sip.dialog.SetupEarly
event is fired.

If then a 2XX final response is received a

javax.sip.dialog.SetupConfirmed
event is fired.

In case of a non 2XX final response a

javax.sip.dialog.SetupFailed
event is fired.

If the dialog setup times out a

javax.sip.dialog.SetupTimedOut
event is fired, this occurs if no final response arrives in time.

The

javax.sip.dialog.Terminated
event is fired when the dialog is terminated which can be done in different ways. The most common is a BYE request but also a NOTIFY can terminate a dialog.

Timeout events

SIP transactions timeout if not completed within a specified time frame. The
javax.sip.Timeout.TRANSACTION
event is used to notify about this. This event is delivered on the corresponding client transaction or server transaction activity.

The

javax.sip.Timeout.DIALOG
event is used to inform an application that a Dialog has ended because it has lasted longer than a certain allowed amount of time without any messages being sent within it.
An example: There is a dialog between two UAs and one of them crashes. The Dialog activity object in a SLEE application may then continue to exist indefinitely if there is no mechanism to free resources related to it.

Example scenarios

Here follows a set of scenarios with events, sip messages sent, and indication of where activities start and end.

Successful INVITE

This flow describes the flow of events for an Sbb that initiates a dialog and ends it sending a BYE.

  1. Sbb attached to dialog ACI & client transaction ACI
  2. Client transaction & dialog activitiy started
  3. INVITE --->
  4. <--- javax.sip.message.Response.Trying on client activity
  5. <--- javax.sip.dialog.SetupEarly on dialog activity
  6. <--- javax.sip.dialog.SetupConfirmed on dialog activity
  7. ACK --->
  8. Client transaction activity ended
  9. Dialog activity continues to exists, here subsequent mid-dialog requests can occur within this activity
  10. Client transaction activity started
  11. BYE ---> (Which should be sent via the javax.sip.Dialog.sendRequest method)
  12. <--- OK
  13. Client transaction & dialog activity ends

Cancelled invitation (original INVITE)

This flow is for an Sbb receiving an INVITE which is later cancelled.

  1. Server transaction activity started
  2. <--- javax.sip.message.Request.INVITE on server transaction activity
  3. Sbb creates dialog and attaches to dialog ACI
  4. Dialog activity started
  5. 180 Ringing --->
  6. UAC Dialog enters early state, now it is legal for the UAC to cancel the request
  7. <--- SIP CANCEL arrives at the RA which responds 200 OK to the CANCEL and 487 “Request Terminated” to the INVITE request being cancelled
  8. <--- javax.sip.message.Request.CANCEL on server transaction activity
  9. Both server transaction and dialog activity ended

(If the Sbb tries to respond 200 OK after the RA has responded 487 “Request Terminated” the RA must throw an IllegalStateException)

Design choices

Response event javax.sip.message.Response.TRYING

The 100 Trying response has a separate event type, which is different from the JAIN SIP 1.1 SIP RA Type. The reason for this is that most applications never use the 100 Trying response directly. It is only used to stop retransmits of the INVITE, and does not contain any other information. Stateful proxies (as opposed to stateless) always drop 100 Trying responses - they never get forwarded. "Informational" (101-199) responses are important to applications, since they will often set up early dialogs or have SDP content.

By making "100 Trying" a separate event type, this makes it easy for the RA to filter out these responses, so they never have to enter the SLEE event router. The RA can know that no services are interested in "100 Trying" events by implementing the serviceActivated/serviceDeactivated callbacks (from JSR 240 EDR) and keeping track of the event types that services require.

If we did not have this separate event type, we would have to always fire an "INFORMATIONAL" event for "100 Trying", even though it is almost certainly not used by any application. This design choice is partly an optimization, partly a cleaner separation of event types that haev different meaning for applications.

Cancellation

In SIP the CANCEL method is used to cancel a previously sent request. The only method that is subject to cancellation (of the core methods defined in RFC 3261) is INVITE because it is the only method that can take a long time to complete.

The CANCEL request is sent in a transaction of its own, although it refers to the transaction to be cancelled (see RFC 3261 for details). When a CANCEL request is received the folllowing procedure is to be perfomed:

  • 1. CANCEL arrives at RA. RA checks to see if it matches a previous ServerTransaction. If there is a match, go to (2), else (3)

  • 2. The CANCEL matches a previous ServerTransaction (INVITE), here the RA can send a 200 OK response for the CANCEL if final response has not been sent, otherwise it should drop CANCEL. ( Actually firing CANCEL and OKing its transaction should be postponed a little bit to give sbbs chance to process INVITE - as it could be to late to CANCEL this INVITE)

  • 2a. If there is also an associated dialog activity, the RA generates the 487 response and ends the dialog activity. The CANCEL event is fired on the ServerTransaction activity to inform the app. The app does not need to do anything else.

  • 2b. If no dialog activity is present, then fire the CANCEL event on the ServerTransaction activity. The app must handle this as appropriately, ie. send a 487 if it is a UAS, or cancel pending branches if it is a proxy.

  • 3. If there is no match, the CANCEL event must be passed up statelessly to the app - a proxy will need to statelessly forward this downstream. Here there is no activity to fire the event on, so the RA will need to create a "one-shot" dummy activity that ends immediately after the event is fired. This one shot activity should implement javax.sip.ServerTransaction. ( Good candidate would be CANCELs ServerTransaction)

  • 4. If the CANCEL did not match any previous ServerTransaction , and the CANCEL event in (3) was not processed by any SBBs (the RA can detect this in the event processing callbacks in the SLEE 1.1 RA API), then I think in this case the RA is safe to respond with "481 Call/Transaction Does Not Exist".

TIP - in order to make this procesing path available when application acts as proxy , application has to remove ServerTransaction associated with INVITE from activities list - for isntance explicitly terminate it. However this would nto be good approach, instead RA implemenattion should give means to notice RA that request with this transaction has been proxied. Or RA should asume that if no dialog has been created after INVITE processing and its TX has not entered terminated state that "we" are acting as proxy.

In step (2) there is a potential race between the SBB sending a final response and the RA firing the CANCEL event. It is up to the RA implementation to resolve this. For example, if the SBB tries to send after the RA has fired the CANCEL event, the RA could detect this and throw an IllegalStateException.

Possible implementation choice for dialog timeout event

Session expiration mechanism based on rfc 4028

Future changes

The following is a list of possible future changes.

Proxy support

There is no special support for proxying messages in the current definition. A natural enhancement would be to add this is some way, possibly with a special proxy activity which would be used to recieve events related to proxing. The RA would take care of the proxy behaviour as specified in RFC 3261.

Forking

INVITEs and SUBSCRIBEs can be forked and this should probably be catered for by the RA Type. One way of doin gthis is to introduce a custom event type to make it explicit that e.g. an additional dialog is created as a result of a response to a forked INVITE.

Transaction stateless behaviour

In the current definition there is always a server transaction activity for incoming requests. To support transaction stateless services it would be necessary to change this one possible way being to simply let the default underlying activity be the SIP request itself and let the application decide if a server transaction be created.

List of contributors to this proposal

  • Open Cloud
  • Mobicents
  • NIST

-- Main.niklasuhrberg - 04 May 2006

Topic DialogExtensionMemo . { Edit | Ref-By | Printable | Diffs r17 < r16 < r15 < r14 < r13 | More }
 XML java.net RSS

Revision r17 - 22 May 2007 - 17:33:51 - Main.baranowb
Parents: WebHome > MobicentsOpenSLEE > MobicentsSIPRA