What is a bound box? Explaining the session key based targeting mechanism

Version 1.1 of the SIP Servlet API introduced the awkwardly named session key based targeting mechanism. This blog explains what it is for, and what a bound box is. As it turns out, they are both pretty useful for a large class of telephony applications.

The session key based targeting mechanism was introduced in version 1.1 to support applications that need to handle an incoming initial request (e.g. an INVITE request) with an existing application session.

To use a concrete example, a Call Waiting (CW) app acts as a transparent B2BUA when Bob is talking to Alice. Later on Carol calls Bob. The CW app will need to switch Bob back and forth between Alice and Carol. It is far easier if the three SipSession's are in the same SipApplicationSession. Normally, the SIP servlet container would create a new SipApplicationSession to handle the INVITE request from Carol. However, using the session key based session targeting mechanism, the CW app can specify that the request should be dispatched to the existing SipApplicationSession.

In E4SS parlance, applications like CW are called bound applications or bound boxes. An application session is bound to the subscriber address it is serving, such that when a new initial request comes in for the same subscriber, the same application session is invoked to handle it. E4SS has built in support for bound applications, and the default behavior may be customized to suit the need of different applications.

Example: busyRejector

In the E4SS SDK, the busyRejector feature is a simple example of a bound application. When its subscriber makes or receives a call, busyRejector is invoked but acts as a transparent B2BUA. It springs to life when a new call comes in for its subscriber — it rejects the new call with 486 Busy Here. It is a good feature to have when you are on one of those all important calls and cannot afford to be interrupted even a tiny bit!

Let's look at the source code in $EDK_HOME/features/busyRejector. The ECharts machine is src/org/echarts/servlet/sip/features/busyRejector/BusyRejectorFSM.ech. The first thing to point out is the class definition of the top-level machine:


/** Machine that provides an example of a bound box. This feature acts
  * transparently for the first call and rejects subsequent calls
  * while the first call is still connected.
  */
 public machine BusyRejectorFSM implements BoundBoxMachine {
    ...

The BoundBoxMachine class is a marker interface for the application programmer to tell E4SS that this is a bound box.

The rest of the machine is pretty much the same as a transparent B2BUA. However, this transition is unique to a bound box:

    /** Reject subsequent calls
     */
    transition IN_CALL - boxPort?Invite / {
        <*
        rejector = box.createSipPort("rejector");
        rejector.bind(message);
        SipServletResponse resp = rejector.createResponse(
            SipServletResponse.SC_BUSY_HERE,
            rejector.getInitialRequest());
        *>
        rejector!resp;
        rejector.destroy();
    } -> DEEP_HISTORY;

Because it is a bound box, new initial requests arrive at the BoxPort of the application instance. In comparison, a non-bound box can only receive one initial request at the BoxPort throughout its lifetime.

This transition fires when the application has an ongoing call (IN_CALL state), and receives an initial INVITE request (boxPort?Invite). It creates a 486 Busy Here response and sends it, then returns to the previous state (DEEP_HISTORY). The finite state machine of BusyRejector is shown below, with the above transition in red:

BusyRejectorFSM machine

Testing busyRejector

We can use the DFC-AR included in E4SS SDK, and the approuter.xml in the busyRejector/test directory to test this application out. See the E4SS manual section 4 for details of how to use the DFC-AR. We have tested it on Oracle Communications Converged Application Server (OCCAS) 4.0 and SailFin v2-b12 successfully. See appendix A.1 and A.2 of the E4SS manual for information for container-specific configuration.

Let's take a look at the test directory to see some KitCAT test cases. In all the test cases, Bob is the subscriber. In testRejection(), Alice calls Bob and is connected. Then Carol calls Bob. Both initial INVITE requests have the same Request-URI, e.g. sip:bob@example.com, and therefore in both cases the DFC-AR returns sip:bob@example.com as the subscriberURI to the container. Then when the container dispatches the request to the application, E4SS calls SipServletRequest.getSubscriberURI() to get the URI of the subscriber and returns its toString() as the session key. As a result, the container dispatches both initial requests to the same application session, i.e. the same bound box.The INVITE from Carol triggers the above transition, and Carol's call is duly rejected.

In testRejectionCaller(), this time Bob called Alice first. DFC-AR selects busyRejector and returns the From header as the subscriberURI, e.g. sip:bob@example.com. Then when Carol calls Bob, the Request-URI is sip:bob@example.com. Again the subscriberURI and thus the session key in both initial requests match, and therefore both requests are dispatched to the same bound box.

Customizing the session key

Under the hood, E4SS defines a @SipApplicationKey annotated method in EChartsSipServlet. If the top-level machine is marked with BoundBoxMachine, the @SipApplicationKey method in turn calls EChartsSipServlet.sessionKeyFromRequest(). If an application needs to customize how the key is generated, it can extend EChartsSipServlet to override sessionKeyFromRequest(). For example, it is often useful to return just the username part of the subscriberURI as the key, so that if the subscriberURI contains different parameters or hostname they do not interfere with the bound box targeting.

The E4SS Javadoc contains more information on these classes and methods.

Last Updated ( Wednesday, 13 May 2009 )